2018-11-24 17:26:26 +01:00
|
|
|
#include "newobjects.h"
|
2018-09-08 18:43:59 +02:00
|
|
|
#include "..\Global\global.h"
|
|
|
|
#include "..\Game\Box.h"
|
|
|
|
#include "..\Game\items.h"
|
|
|
|
#include "..\Game\lot.h"
|
|
|
|
#include "..\Game\control.h"
|
2018-11-26 23:01:24 +01:00
|
|
|
#include "..\Game\people.h"
|
2018-09-08 18:43:59 +02:00
|
|
|
#include "..\Game\effects.h"
|
2018-11-26 23:01:24 +01:00
|
|
|
#include "..\Game\effect2.h"
|
2018-09-08 18:43:59 +02:00
|
|
|
#include "..\Game\draw.h"
|
|
|
|
#include "..\Game\sphere.h"
|
2018-11-26 23:01:24 +01:00
|
|
|
#include "..\Game\inventory.h"
|
2018-11-24 09:39:37 +01:00
|
|
|
#include "..\Game\collide.h"
|
2018-11-26 23:01:24 +01:00
|
|
|
#include "..\Game\draw.h"
|
2018-11-24 09:39:37 +01:00
|
|
|
|
|
|
|
__int16 StargateBounds[24] =
|
|
|
|
{
|
|
|
|
0xFE00, 0x0200, 0xFC00, 0xFC80, 0xFFA0, 0x0060, 0xFE00, 0x0200,
|
|
|
|
0xFF80, 0x0000, 0xFFA0, 0x0060, 0xFE00, 0xFE80, 0xFC00, 0x0000,
|
|
|
|
0xFFA0, 0x0060, 0x0180, 0x0200, 0xFC00, 0x0000, 0xFFA0, 0x0060
|
|
|
|
};
|
2018-09-08 18:43:59 +02:00
|
|
|
|
2018-11-26 23:01:24 +01:00
|
|
|
BITE_INFO sentryGunBite = { 0, 0, 0, 8 };
|
|
|
|
|
2018-09-08 18:43:59 +02:00
|
|
|
void __cdecl FourBladesControl(__int16 itemNum)
|
|
|
|
{
|
|
|
|
ITEM_INFO* item = &Items[itemNum];
|
|
|
|
|
|
|
|
if (!TriggerActive(item))
|
|
|
|
{
|
|
|
|
item->frameNumber = Anims[item->animNumber].frameBase;
|
|
|
|
item->itemFlags[0] = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
__int16 frameNumber = item->frameNumber - Anims[item->animNumber].frameBase;
|
|
|
|
|
|
|
|
if (frameNumber <= 5 || frameNumber >= 58 || frameNumber >= 8 && frameNumber <= 54)
|
|
|
|
item->itemFlags[0] = 0;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (frameNumber >= 6 && frameNumber <= 7)
|
|
|
|
{
|
|
|
|
item->itemFlags[3] = 20;
|
|
|
|
item->itemFlags[0] = 30;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (frameNumber >= 55 && frameNumber <= 57)
|
|
|
|
{
|
|
|
|
item->itemFlags[3] = 200;
|
|
|
|
item->itemFlags[0] = 30;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
AnimateItem(item);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void __cdecl BirdBladeControl(__int16 itemNum)
|
|
|
|
{
|
|
|
|
ITEM_INFO* item = &Items[itemNum];
|
|
|
|
|
|
|
|
item->itemFlags[3] = 100;
|
|
|
|
if (!TriggerActive(item))
|
|
|
|
{
|
|
|
|
item->frameNumber = Anims[item->animNumber].frameBase;
|
|
|
|
item->itemFlags[0] = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
__int16 frameNumber = item->frameNumber - Anims[item->animNumber].frameBase;
|
|
|
|
|
|
|
|
if (frameNumber <= 14 || frameNumber >= 31)
|
|
|
|
item->itemFlags[0] = 0;
|
|
|
|
else
|
|
|
|
item->itemFlags[0] = 6;
|
|
|
|
|
|
|
|
AnimateItem(item);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void __cdecl CatwalkBlaldeControl(__int16 itemNum)
|
|
|
|
{
|
|
|
|
ITEM_INFO* item = &Items[itemNum];
|
|
|
|
|
|
|
|
if (!TriggerActive(item))
|
|
|
|
{
|
|
|
|
item->frameNumber = Anims[item->animNumber].frameBase;
|
|
|
|
item->itemFlags[0] = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
__int16 frameNumber = item->frameNumber - Anims[item->animNumber].frameBase;
|
|
|
|
|
|
|
|
if (item->frameNumber == Anims[item->animNumber].frameEnd || frameNumber < 38)
|
|
|
|
item->itemFlags[3] = 0;
|
|
|
|
else
|
|
|
|
item->itemFlags[3] = 100;
|
|
|
|
|
|
|
|
AnimateItem(item);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void __cdecl PlinthBladeControl(__int16 itemNum)
|
|
|
|
{
|
|
|
|
ITEM_INFO* item = &Items[itemNum];
|
|
|
|
|
|
|
|
if (!TriggerActive(item))
|
|
|
|
{
|
|
|
|
item->frameNumber = Anims[item->animNumber].frameBase;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
__int16 frameNumber = item->frameNumber - Anims[item->animNumber].frameBase;
|
|
|
|
|
|
|
|
if (item->frameNumber == Anims[item->animNumber].frameEnd)
|
|
|
|
item->itemFlags[3] = 0;
|
|
|
|
else
|
|
|
|
item->itemFlags[3] = 200;
|
|
|
|
|
|
|
|
AnimateItem(item);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void __cdecl InitialiseSethBlade(__int16 itemNum)
|
|
|
|
{
|
|
|
|
ITEM_INFO* item = &Items[itemNum];
|
|
|
|
|
|
|
|
item->animNumber = Objects[ID_SETH_BLADE].animIndex + 1;
|
|
|
|
item->goalAnimState = 2;
|
|
|
|
item->currentAnimState = 2;
|
|
|
|
item->frameNumber = Anims[item->animNumber].frameBase;
|
|
|
|
item->itemFlags[2] = abs(item->triggerFlags);
|
|
|
|
}
|
|
|
|
|
|
|
|
void __cdecl SethBladeControl(__int16 itemNum)
|
|
|
|
{
|
|
|
|
ITEM_INFO* item = &Items[itemNum];
|
|
|
|
|
|
|
|
item->itemFlags[0] = 0;
|
|
|
|
if (TriggerActive(item))
|
|
|
|
{
|
|
|
|
if (item->currentAnimState == 2)
|
|
|
|
{
|
|
|
|
if (item->itemFlags[2] > 1)
|
|
|
|
{
|
|
|
|
item->itemFlags[2]--;
|
|
|
|
}
|
|
|
|
else if (item->itemFlags[2] == 1)
|
|
|
|
{
|
|
|
|
item->goalAnimState = 1;
|
|
|
|
item->itemFlags[2] = 0;
|
|
|
|
}
|
|
|
|
else if (!item->itemFlags[2])
|
|
|
|
{
|
|
|
|
if (item->triggerFlags > 0)
|
|
|
|
{
|
|
|
|
item->itemFlags[2] = item->triggerFlags;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
__int16 frameNumber = item->frameNumber - Anims[item->animNumber].frameBase;
|
|
|
|
|
|
|
|
if (item->frameNumber != Anims[item->animNumber].frameBase && frameNumber <= 6)
|
|
|
|
{
|
|
|
|
item->itemFlags[0] = -1;
|
|
|
|
item->itemFlags[3] = 1000;
|
|
|
|
}
|
|
|
|
else if (frameNumber >= 7 && frameNumber <= 15)
|
|
|
|
{
|
|
|
|
item->itemFlags[0] = 448;
|
|
|
|
item->itemFlags[3] = 1000;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
item->itemFlags[0] = 0;
|
|
|
|
item->itemFlags[3] = 1000;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
AnimateItem(item);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void __cdecl ChainControl(__int16 itemNum)
|
|
|
|
{
|
|
|
|
ITEM_INFO* item = &Items[itemNum];
|
|
|
|
|
|
|
|
if (item->triggerFlags)
|
|
|
|
{
|
|
|
|
item->itemFlags[2] = 1;
|
|
|
|
item->itemFlags[3] = 75;
|
|
|
|
|
|
|
|
if (TriggerActive(item))
|
|
|
|
{
|
|
|
|
item->itemFlags[0] = 30846;
|
|
|
|
AnimateItem(item);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
item->itemFlags[3] = 25;
|
|
|
|
|
|
|
|
if (TriggerActive(item))
|
|
|
|
{
|
|
|
|
item->itemFlags[0] = 1920;
|
|
|
|
AnimateItem(item);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
item->itemFlags[0] = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void __cdecl PloughControl(__int16 itemNum)
|
|
|
|
{
|
|
|
|
ITEM_INFO* item = &Items[itemNum];
|
|
|
|
|
|
|
|
item->itemFlags[3] = 50;
|
|
|
|
if (TriggerActive(item))
|
|
|
|
{
|
|
|
|
item->itemFlags[0] = 258048;
|
|
|
|
AnimateItem(item);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
item->itemFlags[0] = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void __cdecl CogControl(__int16 itemNum)
|
|
|
|
{
|
|
|
|
ITEM_INFO* item = &Items[itemNum];
|
|
|
|
|
|
|
|
if (TriggerActive(item))
|
|
|
|
{
|
|
|
|
item->status = ITEM_ACTIVE;
|
|
|
|
// *(_DWORD *)&item->gap4C[5526] = *(_DWORD *)&item->gap4C[5526] & 0xFFFFFFFB | 2;
|
|
|
|
AnimateItem(item);
|
|
|
|
|
|
|
|
if (item->triggerFlags == 666)
|
|
|
|
{
|
|
|
|
PHD_VECTOR pos;
|
|
|
|
GetJointAbsPosition(item, &pos, 0);
|
|
|
|
SoundEffect(65, (PHD_3DPOS *)&pos, 0);
|
|
|
|
|
|
|
|
if (item->frameNumber == Anims[item->animNumber].frameEnd)
|
|
|
|
item->flags &= 0xC1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (item->triggerFlags == 2)
|
|
|
|
{
|
|
|
|
item->status |= ITEM_INVISIBLE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void __cdecl SpikeballControl(__int16 itemNum)
|
|
|
|
{
|
|
|
|
ITEM_INFO* item = &Items[itemNum];
|
|
|
|
|
|
|
|
if (TriggerActive(item))
|
|
|
|
{
|
|
|
|
__int16 frameNumber = item->frameNumber - Anims[item->animNumber].frameBase;
|
|
|
|
|
|
|
|
if ((frameNumber <= 14 || frameNumber >= 24) && (frameNumber < 138 || frameNumber > 140))
|
|
|
|
{
|
|
|
|
if (frameNumber < 141)
|
|
|
|
item->itemFlags[0] = 0;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
item->itemFlags[3] = 50;
|
|
|
|
item->itemFlags[0] = 0x7FF800;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
item->itemFlags[3] = 150;
|
|
|
|
item->itemFlags[0] = 0x7FF800;
|
|
|
|
}
|
|
|
|
|
|
|
|
AnimateItem(item);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
item->frameNumber = Anims[item->animNumber].frameBase;
|
|
|
|
item->itemFlags[0] = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-16 17:09:43 +02:00
|
|
|
void __cdecl StargateControl(__int16 itemNum)
|
|
|
|
{
|
|
|
|
ITEM_INFO* item = &Items[itemNum];
|
|
|
|
item->itemFlags[3] = 50;
|
|
|
|
|
|
|
|
if (TriggerActive(item))
|
|
|
|
{
|
|
|
|
SoundEffect(23, &item->pos, 0);
|
|
|
|
item->itemFlags[0] = 57521664;
|
|
|
|
AnimateItem(item);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
item->itemFlags[0] = 0;
|
|
|
|
}
|
|
|
|
|
2018-11-24 09:39:37 +01:00
|
|
|
void __cdecl StargateCollision(__int16 itemNum, ITEM_INFO* l, COLL_INFO* c)
|
|
|
|
{
|
|
|
|
ITEM_INFO* item = &Items[itemNum];
|
|
|
|
|
|
|
|
if (item->status == ITEM_INVISIBLE)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (TestBoundsCollide(item, l, c->radius))
|
|
|
|
{
|
|
|
|
for (__int32 i = 0; i < 8; i++)
|
|
|
|
{
|
|
|
|
GlobalCollisionBounds.X1 = StargateBounds[3 * i + 0];
|
|
|
|
GlobalCollisionBounds.Y1 = StargateBounds[3 * i + 1];
|
|
|
|
GlobalCollisionBounds.Z1 = StargateBounds[3 * i + 2];
|
|
|
|
|
|
|
|
if (TestWithGlobalCollisionBounds(item, l, c))
|
|
|
|
ItemPushLara(item, l, c, 0, 2);
|
|
|
|
}
|
|
|
|
|
|
|
|
__int32 result = TestCollision(item, l);
|
|
|
|
if (result)
|
|
|
|
{
|
|
|
|
result &= item->itemFlags[0];
|
|
|
|
__int32 flags = item->itemFlags[0];
|
|
|
|
|
|
|
|
if (result)
|
|
|
|
{
|
|
|
|
__int32 j = 0;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
if (result & 1)
|
|
|
|
{
|
|
|
|
GlobalCollisionBounds.X1 = SphereList[j].x - SphereList[j].r - item->pos.xPos;
|
|
|
|
GlobalCollisionBounds.Y1 = SphereList[j].y - SphereList[j].r - item->pos.yPos;
|
|
|
|
GlobalCollisionBounds.Z1 = SphereList[j].z - SphereList[j].r - item->pos.zPos;
|
|
|
|
GlobalCollisionBounds.X2 = SphereList[j].x + SphereList[j].r - item->pos.xPos;
|
|
|
|
GlobalCollisionBounds.Y2 = SphereList[j].y + SphereList[j].r - item->pos.yPos;
|
|
|
|
GlobalCollisionBounds.Z2 = SphereList[j].z + SphereList[j].r - item->pos.zPos;
|
|
|
|
|
|
|
|
__int32 oldX = LaraItem->pos.xPos;
|
|
|
|
__int32 oldY = LaraItem->pos.yPos;
|
|
|
|
__int32 oldZ = LaraItem->pos.zPos;
|
|
|
|
|
|
|
|
if (ItemPushLara(item, l, c, flags & 1, 2))
|
|
|
|
{
|
|
|
|
if ((flags & 1) &&
|
|
|
|
(oldX != LaraItem->pos.xPos || oldY != LaraItem->pos.yPos || oldZ != LaraItem->pos.zPos) &&
|
|
|
|
TriggerActive(item))
|
|
|
|
{
|
|
|
|
DoBloodSplat((GetRandomControl() & 0x3F) + l->pos.xPos - 32,
|
|
|
|
(GetRandomControl() & 0x1F) + SphereList[j].y - 16,
|
|
|
|
(GetRandomControl() & 0x3F) + l->pos.zPos - 32,
|
|
|
|
(GetRandomControl() & 3) + 2,
|
|
|
|
2 * GetRandomControl(),
|
|
|
|
l->roomNumber);
|
|
|
|
LaraItem->hitPoints -= 100;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
result >>= 1;
|
|
|
|
j++;
|
|
|
|
flags >>= 1;
|
|
|
|
|
|
|
|
} while (result);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-09-16 23:47:22 +02:00
|
|
|
void __cdecl ControlSpikeWall(__int16 itemNum)
|
|
|
|
{
|
|
|
|
ITEM_INFO* item = &Items[itemNum];
|
|
|
|
|
|
|
|
/* Move wall */
|
|
|
|
if (TriggerActive(item) && item->status != ITEM_DEACTIVATED)
|
|
|
|
{
|
|
|
|
__int32 x = item->pos.xPos + SIN(item->pos.yRot) >> WALL_SHIFT;
|
|
|
|
__int32 z = item->pos.zPos + COS(item->pos.yRot) >> WALL_SHIFT;
|
2018-09-17 21:13:44 +02:00
|
|
|
|
2018-09-16 23:47:22 +02:00
|
|
|
__int16 roomNumber = item->roomNumber;
|
|
|
|
FLOOR_INFO* floor = GetFloor(x, item->pos.yPos, z, &roomNumber);
|
|
|
|
|
2018-09-22 23:54:36 +02:00
|
|
|
if (GetFloorHeight(floor, x, item->pos.yPos, z) != item->pos.yPos)
|
2018-09-16 23:47:22 +02:00
|
|
|
{
|
|
|
|
item->status = ITEM_DEACTIVATED;
|
|
|
|
StopSoundEffect(147);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
item->pos.xPos = x;
|
|
|
|
item->pos.zPos = z;
|
|
|
|
if (roomNumber != item->roomNumber)
|
|
|
|
ItemNewRoom(itemNum, roomNumber);
|
|
|
|
SoundEffect(147, &item->pos, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (item->touchBits)
|
|
|
|
{
|
|
|
|
LaraItem->hitPoints -= 15;
|
|
|
|
LaraItem->hitStatus = true;
|
|
|
|
|
|
|
|
DoLotsOfBlood(LaraItem->pos.xPos, LaraItem->pos.yPos - 512, LaraItem->pos.zPos, 4, item->pos.yRot, LaraItem->roomNumber, 3);
|
|
|
|
item->touchBits = 0;
|
|
|
|
|
|
|
|
SoundEffect(56, &item->pos, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void __cdecl InitialiseSpinningBlade(__int16 item_number)
|
|
|
|
{
|
|
|
|
ITEM_INFO* item = &Items[item_number];
|
|
|
|
|
|
|
|
item->animNumber = Objects[item->objectNumber].animIndex + 3;
|
|
|
|
item->frameNumber = Anims[item->animNumber].frameBase;
|
|
|
|
item->currentAnimState = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void __cdecl SpinningBlade(__int16 item_number)
|
|
|
|
{
|
|
|
|
bool spinning = false;
|
2018-09-17 21:13:44 +02:00
|
|
|
|
2018-09-16 23:47:22 +02:00
|
|
|
ITEM_INFO* item = &Items[item_number];
|
2018-09-17 21:13:44 +02:00
|
|
|
|
2018-09-16 23:47:22 +02:00
|
|
|
if (item->currentAnimState == 2)
|
|
|
|
{
|
|
|
|
if (item->goalAnimState != 1)
|
|
|
|
{
|
|
|
|
__int32 x = item->pos.xPos + (WALL_SIZE * 3 / 2 * SIN(item->pos.yRot) >> W2V_SHIFT);
|
|
|
|
__int32 z = item->pos.zPos + (WALL_SIZE * 3 / 2 * COS(item->pos.yRot) >> W2V_SHIFT);
|
2018-09-17 21:13:44 +02:00
|
|
|
|
2018-09-16 23:47:22 +02:00
|
|
|
__int16 roomNumber = item->roomNumber;
|
|
|
|
FLOOR_INFO* floor = GetFloor(x, item->pos.yPos, z, &roomNumber);
|
2018-09-22 23:54:36 +02:00
|
|
|
__int32 height = GetFloorHeight(floor, x, item->pos.yPos, z);
|
2018-09-16 23:47:22 +02:00
|
|
|
|
|
|
|
if (height == NO_HEIGHT)
|
|
|
|
item->goalAnimState = 1;
|
|
|
|
}
|
2018-09-17 21:13:44 +02:00
|
|
|
|
2018-09-16 23:47:22 +02:00
|
|
|
spinning = true;
|
|
|
|
|
|
|
|
if (item->touchBits)
|
|
|
|
{
|
|
|
|
LaraItem->hitStatus = true;
|
|
|
|
LaraItem->hitPoints -= 100;
|
|
|
|
|
|
|
|
DoLotsOfBlood(LaraItem->pos.xPos, LaraItem->pos.yPos - STEP_SIZE * 2, LaraItem->pos.zPos, (__int16)(item->speed * 2), LaraItem->pos.yRot, LaraItem->roomNumber, 2);
|
|
|
|
}
|
|
|
|
|
|
|
|
SoundEffect(231, &item->pos, 0);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (TriggerActive(item))
|
|
|
|
item->goalAnimState = 2;
|
|
|
|
spinning = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
AnimateItem(item);
|
|
|
|
|
|
|
|
__int16 roomNumber = item->roomNumber;
|
|
|
|
FLOOR_INFO* floor = GetFloor(item->pos.xPos, item->pos.yPos, item->pos.zPos, &roomNumber);
|
2018-09-22 23:54:36 +02:00
|
|
|
item->floor = item->pos.yPos = GetFloorHeight(floor, item->pos.xPos, item->pos.yPos, item->pos.zPos);
|
2018-09-16 23:47:22 +02:00
|
|
|
if (roomNumber != item->roomNumber)
|
|
|
|
ItemNewRoom(item_number, roomNumber);
|
|
|
|
|
|
|
|
if (spinning && item->currentAnimState == 1)
|
|
|
|
item->pos.yRot += -ANGLE(180);
|
|
|
|
}
|
|
|
|
|
|
|
|
void __cdecl InitialiseKillerStatue(__int16 item_number)
|
|
|
|
{
|
|
|
|
ITEM_INFO* item = &Items[item_number];
|
|
|
|
|
|
|
|
item->animNumber = Objects[item->objectNumber].animIndex + 3;
|
|
|
|
item->frameNumber = Anims[item->animNumber].frameBase;
|
|
|
|
item->currentAnimState = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void __cdecl KillerStatueControl(__int16 item_number)
|
|
|
|
{
|
|
|
|
ITEM_INFO *item;
|
|
|
|
__int32 x, y, z;
|
|
|
|
__int16 d;
|
|
|
|
|
|
|
|
item = &Items[item_number];
|
|
|
|
|
|
|
|
if (TriggerActive(item) && item->currentAnimState == 1)
|
|
|
|
item->goalAnimState = 2;
|
|
|
|
else
|
|
|
|
item->goalAnimState = 1;
|
|
|
|
|
|
|
|
if ((item->touchBits & 0x80) && item->currentAnimState == 2)
|
|
|
|
{
|
|
|
|
LaraItem->hitStatus = 1;
|
|
|
|
LaraItem->hitPoints -= 20;
|
|
|
|
|
|
|
|
__int32 x = LaraItem->pos.xPos + (GetRandomControl() - 16384) / 256;
|
|
|
|
__int32 z = LaraItem->pos.zPos + (GetRandomControl() - 16384) / 256;
|
|
|
|
__int32 y = LaraItem->pos.yPos - GetRandomControl() / 44;
|
|
|
|
__int32 d = (GetRandomControl() - 16384) / 8 + LaraItem->pos.yRot;
|
|
|
|
DoBloodSplat(x, y, z, LaraItem->speed, d, LaraItem->roomNumber);
|
|
|
|
}
|
|
|
|
|
|
|
|
AnimateItem(item);
|
|
|
|
}
|
|
|
|
|
|
|
|
void __cdecl SpringBoardControl(__int16 item_number)
|
|
|
|
{
|
|
|
|
ITEM_INFO* item = &Items[item_number];
|
|
|
|
|
|
|
|
if (item->currentAnimState == 0 && LaraItem->pos.yPos == item->pos.yPos &&
|
|
|
|
(LaraItem->pos.xPos >> WALL_SHIFT) == (item->pos.xPos >> WALL_SHIFT) &&
|
|
|
|
(LaraItem->pos.zPos >> WALL_SHIFT) == (item->pos.zPos >> WALL_SHIFT))
|
|
|
|
{
|
|
|
|
if (LaraItem->hitPoints <= 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (LaraItem->currentAnimState == STATE_LARA_WALK_BACK || LaraItem->currentAnimState == STATE_LARA_RUN_BACK)
|
|
|
|
LaraItem->speed = -LaraItem->speed;
|
|
|
|
|
|
|
|
LaraItem->fallspeed = -240;
|
|
|
|
LaraItem->gravityStatus = true;
|
|
|
|
LaraItem->animNumber = ANIMATION_LARA_FREE_FALL_FORWARD;
|
|
|
|
LaraItem->frameNumber = GF2(ID_LARA, ANIMATION_LARA_FREE_FALL_FORWARD, 0);
|
|
|
|
LaraItem->currentAnimState = STATE_LARA_JUMP_FORWARD;
|
|
|
|
LaraItem->goalAnimState = STATE_LARA_JUMP_FORWARD;
|
|
|
|
|
|
|
|
item->goalAnimState = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
AnimateItem(item);
|
2018-11-24 09:39:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void __cdecl InitialiseSlicerDicer(__int16 itemNum)
|
|
|
|
{
|
|
|
|
ITEM_INFO* item = &Items[itemNum];
|
|
|
|
|
|
|
|
__int32 dx = SIN(item->pos.yRot + ANGLE(90)) >> 5;
|
|
|
|
__int32 dz = COS(item->pos.yRot + ANGLE(90)) >> 5;
|
|
|
|
|
|
|
|
item->pos.xPos += dx;
|
|
|
|
item->pos.zPos += dz;
|
|
|
|
|
|
|
|
item->itemFlags[0] = item->pos.xPos >> 8;
|
|
|
|
item->itemFlags[1] = (item->pos.yPos - 4608) >> 8;
|
|
|
|
item->itemFlags[2] = item->pos.zPos >> 8;
|
|
|
|
item->itemFlags[3] = 50;
|
|
|
|
}
|
|
|
|
|
|
|
|
void __cdecl SlicerDicerControl(__int16 itemNum)
|
|
|
|
{
|
|
|
|
ITEM_INFO* item = &Items[itemNum];
|
|
|
|
|
|
|
|
SoundEffect(20, &item->pos, 0);
|
|
|
|
SoundEffect(12, &item->pos, 0);
|
|
|
|
|
|
|
|
__int32 factor = (9 * COS(item->triggerFlags) << 9 >> W2V_SHIFT) * COS(item->pos.yRot) >> W2V_SHIFT;
|
|
|
|
|
|
|
|
item->pos.xPos = (item->itemFlags[0] << 8) + factor;
|
|
|
|
item->pos.yPos = (item->itemFlags[1] << 8) - 4608 * SIN(item->triggerFlags);
|
|
|
|
item->pos.zPos = (item->itemFlags[2] << 8) + factor;
|
|
|
|
|
|
|
|
item->triggerFlags += 170;
|
|
|
|
|
|
|
|
__int16 roomNumber = item->roomNumber;
|
|
|
|
GetFloor(item->pos.xPos, item->pos.yPos, item->pos.zPos, &roomNumber);
|
|
|
|
if (item->roomNumber != roomNumber)
|
|
|
|
ItemNewRoom(itemNum, roomNumber);
|
|
|
|
|
|
|
|
AnimateItem(item);
|
|
|
|
}
|
|
|
|
|
|
|
|
void __cdecl BladeCollision(__int16 itemNum, ITEM_INFO* l, COLL_INFO* coll)
|
|
|
|
{
|
|
|
|
ITEM_INFO* item = &Items[itemNum];
|
|
|
|
|
|
|
|
if (item->status == ITEM_INVISIBLE)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (item->itemFlags[3]) // Check this
|
|
|
|
{
|
|
|
|
if (TestBoundsCollide(item, l, coll->radius))
|
|
|
|
{
|
|
|
|
__int32 oldX = LaraItem->pos.xPos;
|
|
|
|
__int32 oldY = LaraItem->pos.yPos;
|
|
|
|
__int32 oldZ = LaraItem->pos.zPos;
|
|
|
|
|
|
|
|
__int32 dx = 0;
|
|
|
|
__int32 dy = 0;
|
|
|
|
__int32 dz = 0;
|
|
|
|
|
|
|
|
if (ItemPushLara(item, l, coll, 1, 1))
|
|
|
|
{
|
|
|
|
LaraItem->hitPoints -= item->itemFlags[3];
|
|
|
|
|
|
|
|
dx = oldX - LaraItem->pos.xPos;
|
|
|
|
dy = oldY - LaraItem->pos.yPos;
|
|
|
|
dz = oldZ - LaraItem->pos.zPos;
|
|
|
|
|
|
|
|
if ((dx || dy || dz) && TriggerActive(item))
|
|
|
|
{
|
|
|
|
DoBloodSplat((GetRandomControl() & 0x3F) + l->pos.xPos - 32,
|
|
|
|
l->pos.yPos - (GetRandomControl() & 0x1FF) - 256,
|
|
|
|
(GetRandomControl() & 0x3F) + l->pos.zPos - 32,
|
|
|
|
(GetRandomControl() & 3) + (item->itemFlags[3] >> 5) + 2,
|
|
|
|
2 * GetRandomControl(),
|
|
|
|
l->roomNumber);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!coll->enableBaddiePush)
|
|
|
|
{
|
|
|
|
LaraItem->pos.xPos += dx;
|
|
|
|
LaraItem->pos.yPos += dy;
|
|
|
|
LaraItem->pos.zPos += dz;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-11-26 23:01:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void __cdecl InitialiseMine(__int16 itemNum)
|
|
|
|
{
|
|
|
|
ITEM_INFO* item = &Items[itemNum];
|
|
|
|
|
|
|
|
if (item->triggerFlags)
|
|
|
|
item->meshBits = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void __cdecl MineControl(__int16 itemNum)
|
|
|
|
{
|
|
|
|
ITEM_INFO* item = &Items[itemNum];
|
|
|
|
|
|
|
|
__int32 num = GetSpheres(item, SphereList, true);
|
|
|
|
if (item->itemFlags[0] >= 150)
|
|
|
|
{
|
|
|
|
SoundEffect(105, &item->pos, 0);
|
|
|
|
SoundEffect(106, &item->pos, 0);
|
|
|
|
SoundEffect(105, &item->pos, 0x1800004);
|
|
|
|
|
|
|
|
if (num > 0)
|
|
|
|
{
|
|
|
|
SPHERE* sphere = &SphereList[0];
|
|
|
|
|
|
|
|
for (__int32 i = 0; i < num; i++)
|
|
|
|
{
|
|
|
|
if (i >= 7 && i != 9)
|
|
|
|
{
|
|
|
|
TriggerExplosionSparks(sphere->x, sphere->y, sphere->z, 3, -2, 0, -item->roomNumber);
|
|
|
|
TriggerExplosionSparks(sphere->x, sphere->y, sphere->z, 3, -1, 0, -item->roomNumber);
|
|
|
|
TriggerShockwave((PHD_3DPOS*)sphere, 19922992, (GetRandomControl() & 0x1F) + 112, 545284096, 2048, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
sphere++;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (__int32 i = 0; i < num; i++)
|
|
|
|
ExplodeItemNode(item, i, 0, -128);
|
|
|
|
}
|
|
|
|
|
|
|
|
FlashFadeR = 255;
|
|
|
|
FlashFadeG = 192;
|
|
|
|
FlashFadeB = 64;
|
|
|
|
FlashFader = 32;
|
|
|
|
|
|
|
|
__int16 currentItemNumber = Rooms[item->roomNumber].itemNumber;
|
|
|
|
|
|
|
|
// Make the sentry gun explode?
|
|
|
|
while (currentItemNumber != NO_ITEM)
|
|
|
|
{
|
|
|
|
ITEM_INFO* currentItem = &Items[currentItemNumber];
|
|
|
|
|
|
|
|
if (currentItem->objectNumber == ID_SENTRY_GUN)
|
|
|
|
currentItem->meshBits &= ~0x40;
|
|
|
|
|
|
|
|
currentItemNumber = currentItem->nextItem;
|
|
|
|
}
|
|
|
|
|
|
|
|
KillItem(itemNum);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
item->itemFlags[0]++;
|
|
|
|
|
|
|
|
__int32 something = 4 * item->itemFlags[0];
|
|
|
|
if (something > 255)
|
|
|
|
something = 0;
|
|
|
|
|
|
|
|
for (__int32 i = 0; i < num; i++)
|
|
|
|
{
|
|
|
|
SPHERE* sphere = &SphereList[i];
|
|
|
|
|
|
|
|
if (i == 0 || i > 5)
|
|
|
|
AddFire(sphere->x, sphere->y, sphere->z, 2, item->roomNumber, something);
|
|
|
|
|
|
|
|
sphere++;
|
|
|
|
}
|
|
|
|
|
|
|
|
SoundEffect(150, &item->pos, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void __cdecl MineCollision(__int16 itemNum, ITEM_INFO* l, COLL_INFO* coll)
|
|
|
|
{
|
|
|
|
ITEM_INFO* item = &Items[itemNum];
|
|
|
|
|
|
|
|
if (item->triggerFlags && !item->itemFlags[3])
|
|
|
|
{
|
|
|
|
if (l->animNumber != 432 || l->frameNumber < Anims[item->animNumber].frameBase + 57)
|
|
|
|
{
|
|
|
|
if (TestBoundsCollide(item, l, 512))
|
|
|
|
{
|
|
|
|
TriggerExplosionSparks(item->pos.xPos, item->pos.yPos, item->pos.zPos, 3, -2, 0, item->roomNumber);
|
|
|
|
for (__int32 i = 0; i < 2; i++)
|
|
|
|
TriggerExplosionSparks(item->pos.xPos, item->pos.yPos, item->pos.zPos, 3, -1, 0, item->roomNumber);
|
|
|
|
|
|
|
|
item->meshBits = 1;
|
|
|
|
|
|
|
|
ExplodeItemNode(item, 0, 0, 128);
|
|
|
|
KillItem(itemNum);
|
|
|
|
|
|
|
|
l->animNumber = 438;
|
|
|
|
l->frameNumber = Anims[item->animNumber].frameBase;
|
|
|
|
l->currentAnimState = 8;
|
|
|
|
l->speed = 0;
|
|
|
|
|
|
|
|
SoundEffect(103, &item->pos, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for (__int32 i = 0; i < LevelItems; i++)
|
|
|
|
{
|
|
|
|
ITEM_INFO* currentItem = &Items[i];
|
|
|
|
|
|
|
|
// Explode other mines
|
|
|
|
if (currentItem->objectNumber == ID_MINE && currentItem->status != ITEM_INVISIBLE && !currentItem->triggerFlags)
|
|
|
|
{
|
|
|
|
TriggerExplosionSparks(
|
|
|
|
currentItem->pos.xPos,
|
|
|
|
currentItem->pos.yPos,
|
|
|
|
currentItem->pos.zPos,
|
|
|
|
3,
|
|
|
|
-2,
|
|
|
|
0,
|
|
|
|
currentItem->roomNumber);
|
|
|
|
|
|
|
|
for (__int32 j = 0; j < 2; j++)
|
|
|
|
TriggerExplosionSparks(
|
|
|
|
currentItem->pos.xPos,
|
|
|
|
currentItem->pos.yPos,
|
|
|
|
currentItem->pos.zPos,
|
|
|
|
3,
|
|
|
|
-1,
|
|
|
|
0,
|
|
|
|
currentItem->roomNumber);
|
|
|
|
|
|
|
|
currentItem->meshBits = 1;
|
|
|
|
|
|
|
|
ExplodeItemNode(currentItem, 0, 0, -32);
|
|
|
|
KillItem(i);
|
|
|
|
|
|
|
|
if (!(GetRandomControl() & 3))
|
|
|
|
SoundEffect(103, ¤tItem->pos, 0);
|
|
|
|
|
|
|
|
currentItem->status = ITEM_INVISIBLE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void __cdecl InitialiseSentryGun(__int16 itemNum)
|
|
|
|
{
|
|
|
|
ITEM_INFO* item = &Items[itemNum];
|
|
|
|
|
|
|
|
ClearItem(itemNum);
|
|
|
|
|
|
|
|
item->itemFlags[0] = 0;
|
|
|
|
item->itemFlags[1] = 768;
|
|
|
|
item->itemFlags[2] = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void __cdecl SentryGunControl(__int16 itemNum)
|
|
|
|
{
|
|
|
|
ITEM_INFO* item = &Items[itemNum];
|
|
|
|
|
|
|
|
if (!CreatureActive(itemNum))
|
|
|
|
return;
|
|
|
|
|
|
|
|
CREATURE_INFO* creature = (CREATURE_INFO*)item->data;
|
2018-11-27 11:15:30 +01:00
|
|
|
|
2018-11-26 23:01:24 +01:00
|
|
|
AI_INFO info;
|
2018-11-27 11:15:30 +01:00
|
|
|
__int32 c;
|
2018-11-26 23:01:24 +01:00
|
|
|
|
|
|
|
if (creature)
|
|
|
|
{
|
|
|
|
// Flags set by the ID_MINE object?
|
|
|
|
if (item->meshBits & 0x40)
|
|
|
|
{
|
|
|
|
if (item->itemFlags[0])
|
|
|
|
{
|
|
|
|
PHD_VECTOR pos;
|
|
|
|
|
|
|
|
pos.x = sentryGunBite.x;
|
|
|
|
pos.y = sentryGunBite.y;
|
|
|
|
pos.z = sentryGunBite.z;
|
|
|
|
|
|
|
|
GetJointAbsPosition(item, &pos, sentryGunBite.meshNum);
|
|
|
|
|
|
|
|
TriggerDynamics(pos.x, pos.y, pos.z, 4 * item->itemFlags[0] + 12, 24, 16, 4);
|
|
|
|
|
|
|
|
item->itemFlags[0]--;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (item->itemFlags[0] & 1)
|
|
|
|
item->meshBits |= 0x100;
|
|
|
|
else
|
|
|
|
item->meshBits &= ~0x100;
|
|
|
|
|
|
|
|
if (item->triggerFlags == 0)
|
|
|
|
{
|
|
|
|
item->pos.yPos -= 512;
|
|
|
|
CreatureAIInfo(item, &info);
|
|
|
|
item->pos.yPos += 512;
|
|
|
|
|
2018-11-27 11:15:30 +01:00
|
|
|
__int32 deltaAngle = info.angle - creature->jointRotation[0];
|
2018-11-26 23:01:24 +01:00
|
|
|
|
|
|
|
info.ahead = true;
|
2018-11-27 11:15:30 +01:00
|
|
|
if (deltaAngle <= -ANGLE(90) || deltaAngle >= ANGLE(90))
|
2018-11-26 23:01:24 +01:00
|
|
|
info.ahead = false;
|
|
|
|
|
|
|
|
if (Targetable(item, &info))
|
|
|
|
{
|
|
|
|
if (info.distance < SQUARE(9 * WALL_SIZE))
|
|
|
|
{
|
2018-11-27 11:15:30 +01:00
|
|
|
bool gotPuzzle = HaveIGotItemInInventory(ID_PUZZLE_ITEM5);
|
|
|
|
|
|
|
|
if (!gotPuzzle && !item->itemFlags[0])
|
2018-11-26 23:01:24 +01:00
|
|
|
{
|
2018-11-27 11:15:30 +01:00
|
|
|
if (info.distance <= SQUARE(2048))
|
2018-11-26 23:01:24 +01:00
|
|
|
{
|
2018-11-27 11:15:30 +01:00
|
|
|
SentryGunEffect(item);
|
|
|
|
c = SIN((GlobalCounter & 0x1F) << 11) >> 2;
|
2018-11-26 23:01:24 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-11-27 11:15:30 +01:00
|
|
|
c = 0;
|
2018-11-26 23:01:24 +01:00
|
|
|
item->itemFlags[0] = 2;
|
2018-11-27 11:15:30 +01:00
|
|
|
|
|
|
|
ShotLara(item, &info, &sentryGunBite, creature->jointRotation[0], 5);
|
2018-11-26 23:01:24 +01:00
|
|
|
SoundEffect(358, &item->pos, 0);
|
2018-11-27 11:15:30 +01:00
|
|
|
|
2018-11-26 23:01:24 +01:00
|
|
|
item->itemFlags[2] += 256;
|
|
|
|
if (item->itemFlags[2] > 6144)
|
|
|
|
{
|
|
|
|
item->itemFlags[2] = 6144;
|
|
|
|
}
|
2018-11-27 11:15:30 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
deltaAngle = c + info.angle - creature->jointRotation[0];
|
|
|
|
if (deltaAngle <= ANGLE(10))
|
|
|
|
{
|
|
|
|
if (deltaAngle < -ANGLE(10))
|
|
|
|
{
|
|
|
|
deltaAngle = -ANGLE(10);
|
|
|
|
}
|
2018-11-26 23:01:24 +01:00
|
|
|
}
|
2018-11-27 11:15:30 +01:00
|
|
|
else
|
|
|
|
{
|
|
|
|
deltaAngle = ANGLE(10);
|
|
|
|
}
|
|
|
|
|
|
|
|
creature->jointRotation[0] = deltaAngle - info.xAngle;
|
|
|
|
|
|
|
|
CreatureJoint(item, 1, -info.xAngle);
|
2018-11-26 23:01:24 +01:00
|
|
|
}
|
|
|
|
}
|
2018-11-27 11:15:30 +01:00
|
|
|
|
|
|
|
item->itemFlags[2] -= 32;
|
|
|
|
|
|
|
|
if ((item->itemFlags[2] & 0x8000u) != 0)
|
|
|
|
{
|
|
|
|
item->itemFlags[2] = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
creature->jointRotation[3] += item->itemFlags[2];
|
|
|
|
creature->jointRotation[2] += item->itemFlags[1];
|
|
|
|
|
|
|
|
if (creature->jointRotation[2] > ANGLE(90) ||
|
|
|
|
creature->jointRotation[2] < -ANGLE(90))
|
|
|
|
{
|
|
|
|
item->itemFlags[1] = -item->itemFlags[1];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
CreatureJoint(item, 0, (GetRandomControl() & 0x7FF) - 1024);
|
|
|
|
CreatureJoint(item, 1, ANGLE(45));
|
|
|
|
CreatureJoint(item, 2, (GetRandomControl() & 0x3FFF) - ANGLE(45));
|
2018-11-26 23:01:24 +01:00
|
|
|
}
|
|
|
|
}
|
2018-11-27 11:15:30 +01:00
|
|
|
else
|
|
|
|
{
|
|
|
|
ExplodingDeath(itemNum, -1, 257);
|
|
|
|
DisableBaddieAI(itemNum);
|
|
|
|
KillItem(itemNum);
|
|
|
|
|
|
|
|
item->flags |= 1u;
|
|
|
|
item->status = ITEM_DEACTIVATED;
|
|
|
|
|
|
|
|
RemoveAllItemsInRoom(item->roomNumber, ID_SMOKE_EMITTER_BLACK);
|
|
|
|
|
|
|
|
TriggerExplosionSparks(item->pos.xPos, item->pos.yPos - 768, item->pos.zPos, 3, -2, 0, item->roomNumber);
|
|
|
|
for (__int32 i = 0; i < 2; i++)
|
|
|
|
TriggerExplosionSparks(item->pos.xPos, item->pos.yPos - 768, item->pos.zPos, 3, -1, 0, item->roomNumber);
|
|
|
|
|
|
|
|
SoundEffect(105, &item->pos, 25165828);
|
|
|
|
SoundEffect(106, &item->pos, 0);
|
|
|
|
}
|
2018-11-26 23:01:24 +01:00
|
|
|
}
|
2018-11-27 11:15:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void __cdecl SentryGunEffect(ITEM_INFO* item)
|
|
|
|
{
|
|
|
|
for (__int32 i = 0; i < 3; i++)
|
2018-11-26 23:01:24 +01:00
|
|
|
{
|
2018-11-27 11:15:30 +01:00
|
|
|
SPARKS* spark = &Sparks[GetFreeSpark()];
|
|
|
|
|
|
|
|
spark->on = 1;
|
|
|
|
spark->sR = (GetRandomControl() & 0x1F) + 48;
|
|
|
|
spark->sG = 48;
|
|
|
|
spark->sB = 255;
|
|
|
|
spark->dR = (GetRandomControl() & 0x3F) - 64;
|
|
|
|
spark->dG = (GetRandomControl() & 0x3F) + -128;
|
|
|
|
spark->dB = 32;
|
|
|
|
spark->colFadeSpeed = 12;
|
|
|
|
spark->fadeToBlack = 8;
|
|
|
|
spark->transType = 2;
|
|
|
|
spark->life = spark->sLife = (GetRandomControl() & 0x1F) + 16;
|
|
|
|
|
|
|
|
PHD_VECTOR pos1;
|
|
|
|
pos1.x = -140;
|
|
|
|
pos1.y = -30;
|
|
|
|
pos1.z = -4;
|
|
|
|
|
|
|
|
GetJointAbsPosition(item, &pos1, 7);
|
|
|
|
|
|
|
|
spark->x = (GetRandomControl() & 0x1F) + pos1.x - 16;
|
|
|
|
spark->y = (GetRandomControl() & 0x1F) + pos1.y - 16;
|
|
|
|
spark->z = (GetRandomControl() & 0x1F) + pos1.z - 16;
|
|
|
|
|
|
|
|
PHD_VECTOR pos2;
|
|
|
|
pos2.x = -280;
|
|
|
|
pos2.y = -30;
|
|
|
|
pos2.z = -4;
|
|
|
|
|
|
|
|
GetJointAbsPosition(item, &pos2, 7);
|
|
|
|
|
|
|
|
__int32 v = (GetRandomControl() & 0x3F) + 192;
|
|
|
|
|
|
|
|
spark->xVel = v * (pos2.x - pos1.x) / 10;
|
|
|
|
spark->yVel = v * (pos2.y - pos1.y) / 10;
|
|
|
|
spark->zVel = v * (pos2.z - pos1.z) / 10;
|
|
|
|
|
|
|
|
spark->friction = 85;
|
|
|
|
spark->gravity = -16 - (GetRandomControl() & 0x1F);
|
|
|
|
spark->maxYvel = 0;
|
|
|
|
spark->flags = 538;
|
|
|
|
|
|
|
|
if ((GlobalCounter & 1) != 0)
|
|
|
|
{
|
|
|
|
v = 255;
|
|
|
|
spark->flags = 539;
|
|
|
|
}
|
2018-11-26 23:01:24 +01:00
|
|
|
|
2018-11-27 11:15:30 +01:00
|
|
|
spark->scalar = 3;
|
|
|
|
spark->dSize = v * ((GetRandomControl() & 7) + 60) >> 8;
|
|
|
|
spark->sSize = spark->dSize >> 4;
|
|
|
|
spark->size = spark->dSize >> 4;
|
2018-11-26 23:01:24 +01:00
|
|
|
}
|
2018-12-02 13:09:40 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void __cdecl InitialiseBurningFloor(__int16 itemNum)
|
|
|
|
{
|
|
|
|
Items[itemNum].requiredAnimState = 127;
|
|
|
|
}
|
|
|
|
|
|
|
|
void __cdecl BurningFloorControl(__int16 itemNum)
|
|
|
|
{
|
|
|
|
|
2018-11-27 11:15:30 +01:00
|
|
|
}
|