2020-05-27 09:21:20 +02:00
|
|
|
#include "framework.h"
|
2020-05-27 13:01:32 +02:00
|
|
|
#include "tr3_tony.h"
|
2021-09-25 16:00:30 +03:00
|
|
|
#include "effects/effects.h"
|
2020-05-27 09:21:20 +02:00
|
|
|
#include "items.h"
|
2021-09-19 23:41:26 +03:00
|
|
|
#include "control/lot.h"
|
2020-05-27 13:01:32 +02:00
|
|
|
#include "boss.h"
|
2021-09-19 23:41:26 +03:00
|
|
|
#include "control/box.h"
|
2021-09-16 05:06:03 +03:00
|
|
|
#include "animation.h"
|
2020-05-27 09:21:20 +02:00
|
|
|
#include "level.h"
|
|
|
|
#include "setup.h"
|
|
|
|
#include "lara.h"
|
2021-09-25 16:00:30 +03:00
|
|
|
#include "Sound/sound.h"
|
2021-09-16 05:06:03 +03:00
|
|
|
#include "itemdata/creature_info.h"
|
2021-08-31 17:37:15 +02:00
|
|
|
#include "collide.h"
|
2021-09-22 05:51:25 +02:00
|
|
|
#include "Game/effects/lara_burn.h"
|
2021-09-25 11:27:47 +02:00
|
|
|
|
2021-09-22 05:51:25 +02:00
|
|
|
using namespace TEN::Effects::Fire;
|
2019-11-23 14:49:00 +01:00
|
|
|
|
2020-05-14 18:39:17 +02:00
|
|
|
enum TonyFlameType
|
|
|
|
{
|
|
|
|
T_NOFLAME = 0,
|
2021-03-24 12:49:36 -05:00
|
|
|
T_ROCKZAPPL = 0,
|
|
|
|
T_ROCKZAPPR,
|
|
|
|
T_ZAPP,
|
|
|
|
T_DROPPER,
|
|
|
|
T_ROCKZAPPDEBRIS,
|
|
|
|
T_ZAPPDEBRIS,
|
|
|
|
T_DROPPERDEBRIS
|
2020-05-14 18:39:17 +02:00
|
|
|
};
|
2019-11-23 14:49:00 +01:00
|
|
|
|
2020-05-14 18:39:17 +02:00
|
|
|
struct TONY_FLAME
|
2019-11-23 14:49:00 +01:00
|
|
|
{
|
2020-05-14 18:39:17 +02:00
|
|
|
bool on;
|
|
|
|
PHD_VECTOR pos;
|
|
|
|
int fallspeed;
|
|
|
|
int speed;
|
2020-05-27 13:01:32 +02:00
|
|
|
short yRot;
|
2020-05-14 18:39:17 +02:00
|
|
|
short room_number;
|
|
|
|
TonyFlameType type;
|
2019-11-23 14:49:00 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
enum TONY_STATE
|
|
|
|
{
|
|
|
|
TONYBOSS_WAIT,
|
|
|
|
TONYBOSS_RISE,
|
|
|
|
TONYBOSS_FLOAT,
|
|
|
|
TONYBOSS_ZAPP,
|
|
|
|
TONYBOSS_ROCKZAPP,
|
|
|
|
TONYBOSS_BIGBOOM,
|
|
|
|
TONYBOSS_DEATH
|
|
|
|
};
|
|
|
|
|
2021-03-24 12:49:36 -05:00
|
|
|
static BOSS_STRUCT BossData;
|
2020-05-14 18:39:17 +02:00
|
|
|
#define TONYBOSS_TURN ANGLE(2.0f)
|
2021-09-21 17:18:21 +01:00
|
|
|
#define TONYBOSS_HITS 1 //Tony Harder To Kill, was 100 (6 shotgun shots)
|
2020-05-14 18:39:17 +02:00
|
|
|
#define MAX_TONY_TRIGGER_RANGE 0x4000
|
|
|
|
|
|
|
|
static void TriggerTonyEffect(const TONY_FLAME flame)
|
|
|
|
{
|
|
|
|
short fx_number = CreateNewEffect(flame.room_number);
|
|
|
|
if (fx_number != -1)
|
|
|
|
{
|
2020-06-21 14:27:12 +02:00
|
|
|
FX_INFO* fx = &EffectList[fx_number];
|
2020-05-14 18:39:17 +02:00
|
|
|
fx->pos.xPos = flame.pos.x;
|
|
|
|
fx->pos.yPos = flame.pos.y;
|
|
|
|
fx->pos.zPos = flame.pos.z;
|
|
|
|
fx->fallspeed = flame.fallspeed;
|
|
|
|
fx->pos.xRot = 0;
|
2020-05-27 13:01:32 +02:00
|
|
|
fx->pos.yRot = flame.yRot;
|
2020-05-14 18:39:17 +02:00
|
|
|
fx->pos.zRot = 0;
|
|
|
|
fx->objectNumber = ID_TONY_BOSS_FLAME;
|
|
|
|
fx->speed = flame.speed;
|
|
|
|
fx->shade = 0;
|
|
|
|
fx->flag1 = flame.type;
|
|
|
|
fx->flag2 = (GetRandomControl() & 3) + 1;
|
|
|
|
|
|
|
|
switch (flame.type)
|
|
|
|
{
|
|
|
|
case T_ZAPPDEBRIS:
|
2020-10-17 13:23:01 -05:00
|
|
|
fx->flag2 *= 2;
|
2020-05-14 18:39:17 +02:00
|
|
|
break;
|
|
|
|
case T_ZAPP:
|
|
|
|
fx->flag2 = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-27 13:01:32 +02:00
|
|
|
static void TriggerTonyFlame(short itemNum, int hand)
|
2019-11-23 14:49:00 +01:00
|
|
|
{
|
|
|
|
ITEM_INFO* item;
|
|
|
|
SPARKS* sptr;
|
2020-05-14 18:39:17 +02:00
|
|
|
int dx, dz;
|
2019-11-23 14:49:00 +01:00
|
|
|
|
2020-07-21 09:56:47 +02:00
|
|
|
item = &g_Level.Items[itemNum];
|
2019-11-23 14:49:00 +01:00
|
|
|
dx = LaraItem->pos.xPos - item->pos.xPos;
|
|
|
|
dz = LaraItem->pos.zPos - item->pos.zPos;
|
|
|
|
if (dx < -MAX_TONY_TRIGGER_RANGE || dx > MAX_TONY_TRIGGER_RANGE || dz < -MAX_TONY_TRIGGER_RANGE || dz > MAX_TONY_TRIGGER_RANGE)
|
|
|
|
return;
|
|
|
|
|
|
|
|
sptr = &Sparks[GetFreeSpark()];
|
2020-07-07 07:32:33 +02:00
|
|
|
sptr->on = true;
|
2019-11-23 14:49:00 +01:00
|
|
|
sptr->sR = 255;
|
|
|
|
sptr->sG = 48 + (GetRandomControl() & 31);
|
|
|
|
sptr->sB = 48;
|
|
|
|
sptr->dR = 192 + (GetRandomControl() & 63);
|
|
|
|
sptr->dG = 128 + (GetRandomControl() & 63);
|
|
|
|
sptr->dB = 32;
|
|
|
|
sptr->colFadeSpeed = 12 + (GetRandomControl() & 3);
|
|
|
|
sptr->fadeToBlack = 8;
|
|
|
|
sptr->sLife = sptr->life = (GetRandomControl() & 7) + 24;
|
2021-09-25 16:03:28 -05:00
|
|
|
sptr->transType = TransTypeEnum::COLADD;
|
2020-05-14 18:39:17 +02:00
|
|
|
sptr->extras = NULL;
|
2019-11-23 14:49:00 +01:00
|
|
|
sptr->dynamic = -1;
|
|
|
|
sptr->x = ((GetRandomControl() & 15) - 8);
|
|
|
|
sptr->y = 0;
|
|
|
|
sptr->z = ((GetRandomControl() & 15) - 8);
|
|
|
|
sptr->xVel = ((GetRandomControl() & 255) - 128);
|
|
|
|
sptr->yVel = -(GetRandomControl() & 15) - 16;
|
|
|
|
sptr->zVel = ((GetRandomControl() & 255) - 128);
|
|
|
|
sptr->friction = 5;
|
|
|
|
|
|
|
|
if (GetRandomControl() & 1)
|
|
|
|
{
|
2020-05-14 18:39:17 +02:00
|
|
|
sptr->flags = SP_SCALE | SP_DEF | SP_ROTATE | SP_EXPDEF | SP_ITEM | SP_NODEATTACH;
|
2019-11-23 14:49:00 +01:00
|
|
|
sptr->rotAng = GetRandomControl() & 4095;
|
|
|
|
if (GetRandomControl() & 1)
|
|
|
|
sptr->rotAdd = -(GetRandomControl() & 15) - 16;
|
|
|
|
else
|
|
|
|
sptr->rotAdd = (GetRandomControl() & 15) + 16;
|
|
|
|
}
|
|
|
|
else
|
2020-05-14 18:39:17 +02:00
|
|
|
{
|
|
|
|
sptr->flags = SP_SCALE | SP_DEF | SP_EXPDEF | SP_ITEM | SP_NODEATTACH;
|
|
|
|
}
|
2019-11-23 14:49:00 +01:00
|
|
|
|
|
|
|
sptr->gravity = -(GetRandomControl() & 31) - 16;
|
|
|
|
sptr->maxYvel = -(GetRandomControl() & 7) - 16;
|
|
|
|
sptr->fxObj = itemNum;
|
2020-05-14 18:39:17 +02:00
|
|
|
sptr->nodeNumber = hand;
|
|
|
|
sptr->def = Objects[ID_DEFAULT_SPRITES].meshIndex;
|
2019-11-23 14:49:00 +01:00
|
|
|
sptr->scalar = 1;
|
2020-05-14 18:39:17 +02:00
|
|
|
unsigned char size = (GetRandomControl() & 31) + 32;
|
2019-11-23 14:49:00 +01:00
|
|
|
sptr->size = size;
|
|
|
|
sptr->sSize = size;
|
2020-10-17 13:23:01 -05:00
|
|
|
sptr->dSize = size / 4;
|
2019-11-23 14:49:00 +01:00
|
|
|
}
|
|
|
|
|
2020-05-27 13:01:32 +02:00
|
|
|
static void TriggerFireBallFlame(short fxNumber, long type, long xv, long yv, long zv)
|
2019-11-23 14:49:00 +01:00
|
|
|
{
|
|
|
|
SPARKS* sptr;
|
2020-05-14 18:39:17 +02:00
|
|
|
int dx, dz;
|
2019-11-23 14:49:00 +01:00
|
|
|
|
2020-06-21 14:27:12 +02:00
|
|
|
dx = LaraItem->pos.xPos - EffectList[fxNumber].pos.xPos;
|
|
|
|
dz = LaraItem->pos.zPos - EffectList[fxNumber].pos.zPos;
|
2019-11-23 14:49:00 +01:00
|
|
|
if (dx < -MAX_TONY_TRIGGER_RANGE || dx > MAX_TONY_TRIGGER_RANGE || dz < -MAX_TONY_TRIGGER_RANGE || dz > MAX_TONY_TRIGGER_RANGE)
|
|
|
|
return;
|
|
|
|
|
|
|
|
sptr = &Sparks[GetFreeSpark()];
|
2020-07-07 07:32:33 +02:00
|
|
|
sptr->on = true;
|
2019-11-23 14:49:00 +01:00
|
|
|
sptr->sR = 255;
|
|
|
|
sptr->sG = 48 + (GetRandomControl() & 31);
|
|
|
|
sptr->sB = 48;
|
|
|
|
sptr->dR = 192 + (GetRandomControl() & 63);
|
|
|
|
sptr->dG = 128 + (GetRandomControl() & 63);
|
|
|
|
sptr->dB = 32;
|
|
|
|
sptr->colFadeSpeed = 12 + (GetRandomControl() & 3);
|
|
|
|
sptr->fadeToBlack = 8;
|
|
|
|
sptr->sLife = sptr->life = (GetRandomControl() & 7) + 24;
|
2021-09-25 16:03:28 -05:00
|
|
|
sptr->transType = TransTypeEnum::COLADD;
|
2019-11-23 14:49:00 +01:00
|
|
|
sptr->extras = 0;
|
|
|
|
sptr->dynamic = -1;
|
|
|
|
sptr->x = ((GetRandomControl() & 15) - 8);
|
|
|
|
sptr->y = 0;
|
|
|
|
sptr->z = ((GetRandomControl() & 15) - 8);
|
|
|
|
sptr->xVel = xv + ((GetRandomControl() & 255) - 128);
|
|
|
|
sptr->yVel = yv;
|
|
|
|
sptr->zVel = zv + ((GetRandomControl() & 255) - 128);
|
|
|
|
sptr->friction = 5;
|
|
|
|
|
|
|
|
if (GetRandomControl() & 1)
|
|
|
|
{
|
|
|
|
sptr->flags = SP_SCALE | SP_DEF | SP_ROTATE | SP_EXPDEF | SP_FX;
|
|
|
|
sptr->rotAng = GetRandomControl() & 4095;
|
|
|
|
if (GetRandomControl() & 1)
|
|
|
|
sptr->rotAdd = -(GetRandomControl() & 15) - 16;
|
|
|
|
else
|
|
|
|
sptr->rotAdd = (GetRandomControl() & 15) + 16;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
sptr->flags = SP_SCALE | SP_DEF | SP_EXPDEF | SP_FX;
|
|
|
|
}
|
|
|
|
|
2020-05-14 18:39:17 +02:00
|
|
|
sptr->fxObj = (unsigned char)fxNumber;
|
|
|
|
sptr->def = (unsigned char)Objects[ID_DEFAULT_SPRITES].meshIndex;
|
2019-11-23 14:49:00 +01:00
|
|
|
sptr->scalar = 1;
|
2020-05-14 18:39:17 +02:00
|
|
|
unsigned char size = (GetRandomControl() & 31) + 64;
|
|
|
|
sptr->size = size;
|
|
|
|
sptr->sSize = size;
|
2020-10-17 13:23:01 -05:00
|
|
|
sptr->dSize = size / 4;
|
2019-11-23 14:49:00 +01:00
|
|
|
|
2020-05-14 18:39:17 +02:00
|
|
|
if (type == T_ROCKZAPPL || type == T_ROCKZAPPR)
|
2019-11-23 14:49:00 +01:00
|
|
|
{
|
|
|
|
sptr->gravity = (GetRandomControl() & 31) + 16;
|
|
|
|
sptr->maxYvel = (GetRandomControl() & 15) + 48;
|
2020-10-17 13:23:01 -05:00
|
|
|
sptr->yVel = -sptr->yVel * 16;
|
2019-11-23 14:49:00 +01:00
|
|
|
sptr->scalar = 2;
|
|
|
|
}
|
2020-05-14 18:39:17 +02:00
|
|
|
else if (type == T_ROCKZAPPDEBRIS || type == T_ZAPPDEBRIS || type == T_DROPPERDEBRIS)
|
2019-11-23 14:49:00 +01:00
|
|
|
{
|
2020-05-14 18:39:17 +02:00
|
|
|
sptr->gravity = 0;
|
|
|
|
sptr->maxYvel = 0;
|
2019-11-23 14:49:00 +01:00
|
|
|
}
|
2020-05-14 18:39:17 +02:00
|
|
|
else if (type == T_DROPPER)
|
2019-11-23 14:49:00 +01:00
|
|
|
{
|
|
|
|
sptr->gravity = -(GetRandomControl() & 31) - 16;
|
|
|
|
sptr->maxYvel = -(GetRandomControl() & 31) - 64;
|
2020-10-17 13:23:01 -05:00
|
|
|
sptr->yVel = sptr->yVel * 16;
|
2019-11-23 14:49:00 +01:00
|
|
|
sptr->scalar = 2;
|
|
|
|
}
|
2020-05-14 18:39:17 +02:00
|
|
|
else if (type == T_ZAPP)
|
2019-11-23 14:49:00 +01:00
|
|
|
{
|
|
|
|
sptr->gravity = sptr->maxYvel = 0;
|
|
|
|
sptr->scalar = 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-27 13:01:32 +02:00
|
|
|
static void TriggerFireBall(ITEM_INFO* item, TonyFlameType type, PHD_VECTOR* lara_pos, short roomNumber, short angle, int zdspeed)
|
2019-11-23 14:49:00 +01:00
|
|
|
{
|
2020-05-14 18:39:17 +02:00
|
|
|
TONY_FLAME flame;
|
|
|
|
memset(&flame, 0, sizeof(TONY_FLAME));
|
2019-11-23 14:49:00 +01:00
|
|
|
|
2020-05-14 18:39:17 +02:00
|
|
|
switch (type)
|
2019-11-23 14:49:00 +01:00
|
|
|
{
|
2020-05-14 18:39:17 +02:00
|
|
|
case T_ROCKZAPPL:
|
|
|
|
flame.on = true;
|
|
|
|
flame.pos.x = 0;
|
|
|
|
flame.pos.y = 0;
|
|
|
|
flame.pos.z = 0;
|
|
|
|
GetJointAbsPosition(item, &flame.pos, 10);
|
|
|
|
flame.fallspeed = -16;
|
|
|
|
flame.speed = 0;
|
2020-05-27 13:01:32 +02:00
|
|
|
flame.yRot = item->pos.yRot;
|
2020-05-14 18:39:17 +02:00
|
|
|
flame.room_number = roomNumber;
|
|
|
|
flame.type = T_ROCKZAPPL;
|
|
|
|
break;
|
|
|
|
case T_ROCKZAPPR:
|
|
|
|
flame.on = true;
|
|
|
|
flame.pos.x = 0;
|
|
|
|
flame.pos.y = 0;
|
|
|
|
flame.pos.z = 0;
|
|
|
|
GetJointAbsPosition(item, &flame.pos, 13);
|
|
|
|
flame.fallspeed = -16;
|
|
|
|
flame.speed = 0;
|
2020-05-27 13:01:32 +02:00
|
|
|
flame.yRot = item->pos.yRot;
|
2020-05-14 18:39:17 +02:00
|
|
|
flame.room_number = roomNumber;
|
|
|
|
flame.type = T_ROCKZAPPR;
|
|
|
|
break;
|
|
|
|
case T_ZAPP:
|
|
|
|
flame.on = true;
|
|
|
|
flame.pos.x = 0;
|
|
|
|
flame.pos.y = 0;
|
|
|
|
flame.pos.z = 0;
|
|
|
|
GetJointAbsPosition(item, &flame.pos, 13);
|
|
|
|
flame.fallspeed = (GetRandomControl() & 7) + 10;
|
|
|
|
flame.speed = 160;
|
2020-05-27 13:01:32 +02:00
|
|
|
flame.yRot = item->pos.yRot;
|
2020-05-14 18:39:17 +02:00
|
|
|
flame.room_number = roomNumber;
|
|
|
|
flame.type = T_ZAPP;
|
|
|
|
break;
|
|
|
|
case T_DROPPER:
|
|
|
|
flame.on = true;
|
|
|
|
flame.pos.x = lara_pos->x;
|
2021-03-24 12:49:36 -05:00
|
|
|
flame.pos.y = lara_pos->y + 64;
|
2020-05-14 18:39:17 +02:00
|
|
|
flame.pos.z = lara_pos->z;
|
|
|
|
flame.fallspeed = (GetRandomControl() & 3) + 4;
|
|
|
|
flame.speed = 0;
|
2020-05-27 13:01:32 +02:00
|
|
|
flame.yRot = angle;
|
2020-05-14 18:39:17 +02:00
|
|
|
flame.room_number = roomNumber;
|
|
|
|
flame.type = T_DROPPER;
|
|
|
|
break;
|
|
|
|
case T_ROCKZAPPDEBRIS:
|
|
|
|
flame.on = true;
|
|
|
|
flame.pos.x = lara_pos->x;
|
|
|
|
flame.pos.y = lara_pos->y;
|
|
|
|
flame.pos.z = lara_pos->z;
|
|
|
|
flame.fallspeed = (GetRandomControl() & 3) - 2;
|
|
|
|
flame.speed = zdspeed + (GetRandomControl() & 3);
|
2020-10-17 13:23:01 -05:00
|
|
|
flame.yRot = GetRandomControl() * 2;
|
2020-05-14 18:39:17 +02:00
|
|
|
flame.room_number = roomNumber;
|
|
|
|
flame.type = T_ROCKZAPPDEBRIS;
|
|
|
|
break;
|
|
|
|
case T_ZAPPDEBRIS:
|
|
|
|
flame.on = true;
|
|
|
|
flame.pos.x = lara_pos->x;
|
|
|
|
flame.pos.y = lara_pos->y;
|
|
|
|
flame.pos.z = lara_pos->z;
|
|
|
|
flame.fallspeed = -(GetRandomControl() & 15) - 16;
|
|
|
|
flame.speed = (GetRandomControl() & 7) + 48;
|
2019-11-23 14:49:00 +01:00
|
|
|
angle += (GetRandomControl() & 0x1fff) - 0x9000;
|
2020-05-27 13:01:32 +02:00
|
|
|
flame.yRot = angle;
|
2020-05-14 18:39:17 +02:00
|
|
|
flame.room_number = roomNumber;
|
|
|
|
flame.type = T_ZAPPDEBRIS;
|
|
|
|
break;
|
|
|
|
case T_DROPPERDEBRIS:
|
|
|
|
flame.on = true;
|
|
|
|
flame.pos.x = lara_pos->x;
|
|
|
|
flame.pos.y = lara_pos->y;
|
|
|
|
flame.pos.z = lara_pos->z;
|
|
|
|
flame.fallspeed = -(GetRandomControl() & 31) - 32;
|
|
|
|
flame.speed = (GetRandomControl() & 31) + 32;
|
2020-10-17 13:23:01 -05:00
|
|
|
flame.yRot = GetRandomControl() * 2;
|
2020-05-14 18:39:17 +02:00
|
|
|
flame.room_number = roomNumber;
|
|
|
|
flame.type = T_DROPPERDEBRIS;
|
|
|
|
break;
|
2019-11-23 14:49:00 +01:00
|
|
|
}
|
|
|
|
|
2020-05-14 18:39:17 +02:00
|
|
|
if (flame.on)
|
|
|
|
TriggerTonyEffect(flame);
|
2019-11-23 14:49:00 +01:00
|
|
|
}
|
|
|
|
|
2020-05-14 18:39:17 +02:00
|
|
|
void ControlTonyFireBall(short fxNumber)
|
2019-11-23 14:49:00 +01:00
|
|
|
{
|
|
|
|
FX_INFO* fx;
|
|
|
|
FLOOR_INFO* floor;
|
|
|
|
long old_x, old_y, old_z, x;
|
2020-05-14 18:39:17 +02:00
|
|
|
long rnd, j;
|
2019-11-23 14:49:00 +01:00
|
|
|
unsigned char radtab[7] = { 16,0,14,9,7,7,7 };
|
2020-05-14 18:39:17 +02:00
|
|
|
TonyFlameType type;
|
|
|
|
short room_number;
|
2019-11-23 14:49:00 +01:00
|
|
|
|
2020-06-21 14:27:12 +02:00
|
|
|
fx = &EffectList[fxNumber];
|
2019-11-23 14:49:00 +01:00
|
|
|
old_x = fx->pos.xPos;
|
|
|
|
old_y = fx->pos.yPos;
|
|
|
|
old_z = fx->pos.zPos;
|
|
|
|
|
2020-05-14 18:39:17 +02:00
|
|
|
if (fx->flag1 == T_ROCKZAPPL || fx->flag1 == T_ROCKZAPPR)
|
2019-11-23 14:49:00 +01:00
|
|
|
{
|
2020-10-17 13:23:01 -05:00
|
|
|
fx->fallspeed += (fx->fallspeed / 8) + 1;
|
2019-11-23 14:49:00 +01:00
|
|
|
if (fx->fallspeed < -4096)
|
|
|
|
fx->fallspeed = -4096;
|
|
|
|
fx->pos.yPos += fx->fallspeed;
|
|
|
|
if (Wibble & 4)
|
2020-05-14 18:39:17 +02:00
|
|
|
TriggerFireBallFlame(fxNumber, (TonyFlameType)fx->flag1, 0, 0, 0);
|
2019-11-23 14:49:00 +01:00
|
|
|
}
|
2020-05-14 18:39:17 +02:00
|
|
|
else if (fx->flag1 == T_DROPPER)
|
2019-11-23 14:49:00 +01:00
|
|
|
{
|
|
|
|
fx->fallspeed += 2;
|
|
|
|
fx->pos.yPos += fx->fallspeed;
|
|
|
|
if (Wibble & 4)
|
2020-05-14 18:39:17 +02:00
|
|
|
TriggerFireBallFlame(fxNumber, (TonyFlameType)fx->flag1, 0, 0, 0);
|
2019-11-23 14:49:00 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-05-14 18:39:17 +02:00
|
|
|
if (fx->flag1 != T_ZAPP)
|
2019-11-23 14:49:00 +01:00
|
|
|
{
|
|
|
|
if (fx->speed > 48)
|
|
|
|
fx->speed--;
|
|
|
|
}
|
|
|
|
fx->fallspeed += fx->flag2;
|
|
|
|
if (fx->fallspeed > 512)
|
|
|
|
fx->fallspeed = 512;
|
2020-10-17 13:23:01 -05:00
|
|
|
fx->pos.yPos += fx->fallspeed / 2;
|
2020-10-05 22:24:57 -03:00
|
|
|
fx->pos.zPos += fx->speed * phd_cos(fx->pos.yRot);
|
|
|
|
fx->pos.xPos += fx->speed * phd_sin(fx->pos.yRot);
|
2019-11-23 14:49:00 +01:00
|
|
|
if (Wibble & 4)
|
2020-10-17 13:23:01 -05:00
|
|
|
TriggerFireBallFlame(fxNumber, (TonyFlameType)fx->flag1, (short)((old_x - fx->pos.xPos) * 8), (short)((old_y - fx->pos.yPos) * 8), (short)((old_z - fx->pos.zPos) * 4));
|
2019-11-23 14:49:00 +01:00
|
|
|
}
|
|
|
|
|
2020-05-14 18:39:17 +02:00
|
|
|
room_number = fx->roomNumber;
|
|
|
|
floor = GetFloor(fx->pos.xPos, fx->pos.yPos, fx->pos.zPos, &room_number);
|
|
|
|
if (fx->pos.yPos >= GetFloorHeight(floor, fx->pos.xPos, fx->pos.yPos, fx->pos.zPos) ||
|
|
|
|
fx->pos.yPos < GetCeiling(floor, fx->pos.xPos, fx->pos.yPos, fx->pos.zPos))
|
2019-11-23 14:49:00 +01:00
|
|
|
{
|
2020-05-14 18:39:17 +02:00
|
|
|
if (fx->flag1 == T_ROCKZAPPL || fx->flag1 == T_ROCKZAPPR || fx->flag1 == T_ZAPP || fx->flag1 == T_DROPPER)
|
2019-11-23 14:49:00 +01:00
|
|
|
{
|
2020-05-14 18:39:17 +02:00
|
|
|
PHD_VECTOR pos;
|
2019-11-23 14:49:00 +01:00
|
|
|
|
2021-03-24 12:49:36 -05:00
|
|
|
TriggerExplosionSparks(old_x, old_y, old_z, 3, -2, 0, fx->roomNumber);
|
2020-05-14 18:39:17 +02:00
|
|
|
if (fx->flag1 == T_ROCKZAPPL || fx->flag1 == T_ROCKZAPPR)
|
2019-11-23 14:49:00 +01:00
|
|
|
{
|
|
|
|
for (x = 0; x < 2; x++)
|
|
|
|
TriggerExplosionSparks(old_x, old_y, old_z, 3, -1, 0, fx->roomNumber);
|
|
|
|
}
|
|
|
|
pos.x = old_x;
|
|
|
|
pos.y = old_y;
|
|
|
|
pos.z = old_z;
|
2020-05-14 18:39:17 +02:00
|
|
|
if (fx->flag1 == T_ZAPP)
|
|
|
|
j = 7;
|
2019-11-23 14:49:00 +01:00
|
|
|
else
|
2020-05-14 18:39:17 +02:00
|
|
|
j = 3;
|
|
|
|
if (fx->flag1 == T_ZAPP)
|
|
|
|
type = T_ZAPPDEBRIS;
|
|
|
|
else if (fx->flag1 == T_DROPPER)
|
|
|
|
type = T_DROPPERDEBRIS;
|
2019-11-23 14:49:00 +01:00
|
|
|
else
|
2020-05-14 18:39:17 +02:00
|
|
|
type = T_ROCKZAPPDEBRIS;
|
2019-11-23 14:49:00 +01:00
|
|
|
|
2020-05-14 18:39:17 +02:00
|
|
|
for (x = 0; x < j; x++)
|
2020-10-17 13:23:01 -05:00
|
|
|
TriggerFireBall(NULL, type, &pos, fx->roomNumber, fx->pos.yRot, 32 + (x * 4));
|
2019-11-23 14:49:00 +01:00
|
|
|
|
2020-05-14 18:39:17 +02:00
|
|
|
if (fx->flag1 == T_ROCKZAPPL || fx->flag1 == T_ROCKZAPPR)
|
2019-11-23 14:49:00 +01:00
|
|
|
{
|
2020-05-14 18:39:17 +02:00
|
|
|
room_number = LaraItem->roomNumber;
|
|
|
|
floor = GetFloor(LaraItem->pos.xPos, LaraItem->pos.yPos, LaraItem->pos.zPos, &room_number);
|
2019-11-23 14:49:00 +01:00
|
|
|
pos.y = GetCeiling(floor, LaraItem->pos.xPos, LaraItem->pos.yPos, LaraItem->pos.zPos) + 256;
|
|
|
|
pos.x = LaraItem->pos.xPos + (GetRandomControl() & 1023) - 512;
|
|
|
|
pos.z = LaraItem->pos.zPos + (GetRandomControl() & 1023) - 512;
|
2021-03-24 12:49:36 -05:00
|
|
|
TriggerExplosionSparks(pos.x, pos.y, pos.z, 3, -2, 0, room_number);
|
2020-05-14 18:39:17 +02:00
|
|
|
TriggerFireBall(NULL, T_DROPPER, &pos, room_number, 0, 0);
|
2019-11-23 14:49:00 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
KillEffect(fxNumber);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-07-21 09:56:47 +02:00
|
|
|
if (g_Level.Rooms[room_number].flags & LW_UNDERWATER)
|
2019-11-23 14:49:00 +01:00
|
|
|
{
|
|
|
|
KillEffect(fxNumber);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!Lara.burn)
|
|
|
|
{
|
|
|
|
if (ItemNearLara(&fx->pos, 200))
|
|
|
|
{
|
2020-07-07 07:32:33 +02:00
|
|
|
LaraItem->hitStatus = true;
|
2019-11-23 14:49:00 +01:00
|
|
|
KillEffect(fxNumber);
|
2020-05-14 18:39:17 +02:00
|
|
|
LaraItem->hitPoints -= 200;
|
2021-09-21 17:18:21 +01:00
|
|
|
//LaraBurn();
|
2019-11-23 14:49:00 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-14 18:39:17 +02:00
|
|
|
if (room_number != fx->roomNumber)
|
2019-11-23 14:49:00 +01:00
|
|
|
EffectNewRoom(fxNumber, LaraItem->roomNumber);
|
|
|
|
|
|
|
|
if (radtab[fx->flag1])
|
|
|
|
{
|
|
|
|
rnd = GetRandomControl();
|
2020-10-17 13:23:01 -05:00
|
|
|
BYTE r3 = 31 - ((rnd / 16) & 3);
|
|
|
|
BYTE g3 = 24 - ((rnd / 64) & 3);
|
2020-05-14 18:39:17 +02:00
|
|
|
BYTE b3 = rnd & 7;
|
|
|
|
TriggerDynamicLight(fx->pos.xPos, fx->pos.yPos, fx->pos.zPos, radtab[fx->flag1], r3, g3, b3);
|
2019-11-23 14:49:00 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-27 13:01:32 +02:00
|
|
|
static void TonyBossDie(short itemNum)
|
2019-11-23 14:49:00 +01:00
|
|
|
{
|
|
|
|
ITEM_INFO* item;
|
2020-07-21 09:56:47 +02:00
|
|
|
item = &g_Level.Items[itemNum];
|
2020-07-07 07:32:33 +02:00
|
|
|
item->collidable = false;
|
2020-05-14 18:39:17 +02:00
|
|
|
item->hitPoints = -16384;
|
2019-11-23 14:49:00 +01:00
|
|
|
|
|
|
|
KillItem(itemNum);
|
|
|
|
DisableBaddieAI(itemNum);
|
|
|
|
|
|
|
|
item->flags |= ONESHOT;
|
|
|
|
}
|
|
|
|
|
2019-12-02 14:49:19 +01:00
|
|
|
void InitialiseTony(short itemNum)
|
2019-11-23 14:49:00 +01:00
|
|
|
{
|
|
|
|
ITEM_INFO* item;
|
2020-07-21 09:56:47 +02:00
|
|
|
item = &g_Level.Items[itemNum];
|
2019-11-23 14:49:00 +01:00
|
|
|
item->itemFlags[3] = 0;
|
2020-05-14 18:39:17 +02:00
|
|
|
BossData.ExplodeCount = 0;
|
|
|
|
BossData.RingCount = 0;
|
|
|
|
BossData.DroppedIcon = false;
|
2021-03-24 12:49:36 -05:00
|
|
|
BossData.DrawExplode = false;
|
2020-05-14 18:39:17 +02:00
|
|
|
BossData.Dead = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool TonyIsDying()
|
|
|
|
{
|
|
|
|
return BossData.ExplodeCount == 01 ||
|
|
|
|
BossData.ExplodeCount == 15 ||
|
|
|
|
BossData.ExplodeCount == 25 ||
|
|
|
|
BossData.ExplodeCount == 35 ||
|
|
|
|
BossData.ExplodeCount == 45 ||
|
|
|
|
BossData.ExplodeCount == 55;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void ExplodeTonyBoss(ITEM_INFO* item)
|
|
|
|
{
|
|
|
|
if (item->hitPoints <= 0 && TonyIsDying())
|
2019-11-23 14:49:00 +01:00
|
|
|
{
|
2020-05-14 18:39:17 +02:00
|
|
|
int x, y, z;
|
|
|
|
x = item->pos.xPos + (GetRandomDraw() & 0x3FF) - 512;
|
|
|
|
y = item->pos.yPos - (GetRandomDraw() & 0x3FF) - 256;
|
|
|
|
z = item->pos.zPos + (GetRandomDraw() & 0x3FF) - 512;
|
|
|
|
BossData.DrawExplode = true;
|
|
|
|
|
|
|
|
TriggerExplosionSparks(x, y, z, 3, -2, 0, item->roomNumber);
|
|
|
|
for (int i = 0; i < 2; i++)
|
|
|
|
TriggerExplosionSparks(x, y, z, 3, -1, 0, item->roomNumber);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (BossData.DrawExplode)
|
|
|
|
{
|
|
|
|
BossData.DrawExplode = false;
|
2019-11-23 14:49:00 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-12-02 14:49:19 +01:00
|
|
|
void TonyControl(short itemNum)
|
2019-11-23 14:49:00 +01:00
|
|
|
{
|
|
|
|
ITEM_INFO* item;
|
|
|
|
CREATURE_INFO* tonyboss;
|
|
|
|
AI_INFO info;
|
|
|
|
PHD_VECTOR pos1;
|
2019-11-27 15:12:35 +01:00
|
|
|
short angle, head, torso_x, torso_y, tilt, lp;
|
2019-11-23 14:49:00 +01:00
|
|
|
int rnd;
|
|
|
|
|
|
|
|
if (!CreatureActive(itemNum))
|
|
|
|
return;
|
|
|
|
|
2020-07-21 09:56:47 +02:00
|
|
|
item = &g_Level.Items[itemNum];
|
2019-11-23 14:49:00 +01:00
|
|
|
tonyboss = (CREATURE_INFO*)item->data;
|
|
|
|
head = torso_y = torso_x = angle = tilt = 0;
|
|
|
|
|
|
|
|
if (item->hitPoints <= 0)
|
|
|
|
{
|
|
|
|
if (item->currentAnimState != 6)
|
|
|
|
{
|
|
|
|
item->animNumber = Objects[item->objectNumber].animIndex + 6;
|
2020-07-21 09:56:47 +02:00
|
|
|
item->frameNumber = g_Level.Anims[item->animNumber].frameBase;
|
2019-11-23 14:49:00 +01:00
|
|
|
item->currentAnimState = 6;
|
|
|
|
}
|
2020-05-14 18:39:17 +02:00
|
|
|
|
2020-07-21 09:56:47 +02:00
|
|
|
if ((item->frameNumber - g_Level.Anims[item->animNumber].frameBase) > 110)
|
2020-05-14 18:39:17 +02:00
|
|
|
{
|
|
|
|
item->meshBits = 0;
|
|
|
|
if (!BossData.DroppedIcon)
|
|
|
|
BossData.DroppedIcon = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (BossData.ExplodeCount < 256)
|
|
|
|
BossData.ExplodeCount++;
|
|
|
|
|
|
|
|
if (BossData.ExplodeCount <= 128 || BossData.RingCount != 6)
|
|
|
|
{
|
|
|
|
ExplodeTonyBoss(item);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
TonyBossDie(itemNum);
|
|
|
|
BossData.Dead = true;
|
|
|
|
}
|
2019-11-23 14:49:00 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2021-03-24 12:49:36 -05:00
|
|
|
if (item->itemFlags[3] != 2)
|
2019-11-23 14:49:00 +01:00
|
|
|
item->hitPoints = TONYBOSS_HITS;
|
|
|
|
|
|
|
|
CreatureAIInfo(item, &info);
|
|
|
|
|
2021-03-24 12:49:36 -05:00
|
|
|
if (!item->itemFlags[3])
|
2019-11-23 14:49:00 +01:00
|
|
|
{
|
2020-05-14 18:39:17 +02:00
|
|
|
int dx, dz;
|
2019-11-23 14:49:00 +01:00
|
|
|
dx = item->pos.xPos - LaraItem->pos.xPos;
|
|
|
|
dz = item->pos.zPos - LaraItem->pos.zPos;
|
|
|
|
if ((SQUARE(dx) + SQUARE(dz)) < SQUARE(5120))
|
|
|
|
item->itemFlags[3] = 1;
|
|
|
|
angle = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
tonyboss->target.x = LaraItem->pos.xPos;
|
|
|
|
tonyboss->target.z = LaraItem->pos.zPos;
|
|
|
|
angle = CreatureTurn(item, tonyboss->maximumTurn);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (info.ahead)
|
|
|
|
head = info.angle;
|
|
|
|
|
|
|
|
switch (item->currentAnimState)
|
|
|
|
{
|
2021-03-24 12:49:36 -05:00
|
|
|
case TONYBOSS_WAIT:
|
2019-11-23 14:49:00 +01:00
|
|
|
tonyboss->maximumTurn = 0;
|
|
|
|
if (item->goalAnimState != TONYBOSS_RISE && item->itemFlags[3])
|
|
|
|
item->goalAnimState = TONYBOSS_RISE;
|
|
|
|
break;
|
|
|
|
|
2021-03-24 12:49:36 -05:00
|
|
|
case TONYBOSS_RISE:
|
2020-07-21 09:56:47 +02:00
|
|
|
if ((item->frameNumber - g_Level.Anims[item->animNumber].frameBase) > 16)
|
2019-11-23 14:49:00 +01:00
|
|
|
tonyboss->maximumTurn = TONYBOSS_TURN;
|
|
|
|
else
|
|
|
|
tonyboss->maximumTurn = 0;
|
|
|
|
break;
|
|
|
|
|
2021-03-24 12:49:36 -05:00
|
|
|
case TONYBOSS_FLOAT:
|
2019-11-23 14:49:00 +01:00
|
|
|
torso_y = info.angle;
|
|
|
|
torso_x = info.xAngle;
|
|
|
|
tonyboss->maximumTurn = TONYBOSS_TURN;
|
|
|
|
|
2020-05-14 18:39:17 +02:00
|
|
|
if (!BossData.ExplodeCount)
|
2019-11-23 14:49:00 +01:00
|
|
|
{
|
|
|
|
if (item->goalAnimState != TONYBOSS_BIGBOOM && item->itemFlags[3] != 2)
|
|
|
|
{
|
|
|
|
item->goalAnimState = TONYBOSS_BIGBOOM;
|
|
|
|
tonyboss->maximumTurn = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (item->goalAnimState != TONYBOSS_ROCKZAPP && item->itemFlags[3] == 2)
|
|
|
|
{
|
|
|
|
if (!(Wibble & 255) && item->itemFlags[0] == 0)
|
|
|
|
{
|
|
|
|
item->goalAnimState = TONYBOSS_ROCKZAPP;
|
|
|
|
item->itemFlags[0] = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (item->goalAnimState != TONYBOSS_ZAPP && item->goalAnimState != TONYBOSS_ROCKZAPP && item->itemFlags[3] == 2)
|
|
|
|
{
|
|
|
|
if (!(Wibble & 255) && item->itemFlags[0] == 1)
|
|
|
|
{
|
|
|
|
item->goalAnimState = TONYBOSS_ZAPP;
|
|
|
|
item->itemFlags[0] = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2021-03-24 12:49:36 -05:00
|
|
|
case TONYBOSS_ROCKZAPP:
|
2019-11-23 14:49:00 +01:00
|
|
|
torso_y = info.angle;
|
|
|
|
torso_x = info.xAngle;
|
|
|
|
tonyboss->maximumTurn = 0;
|
|
|
|
|
2020-07-21 09:56:47 +02:00
|
|
|
if (item->frameNumber - g_Level.Anims[item->animNumber].frameBase == 40)
|
2019-11-23 14:49:00 +01:00
|
|
|
{
|
2020-05-14 18:39:17 +02:00
|
|
|
TriggerFireBall(item, T_ROCKZAPPL, NULL, item->roomNumber, 0, 0);
|
|
|
|
TriggerFireBall(item, T_ROCKZAPPR, NULL, item->roomNumber, 0, 0);
|
2019-11-23 14:49:00 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2021-03-24 12:49:36 -05:00
|
|
|
case TONYBOSS_ZAPP:
|
2019-11-23 14:49:00 +01:00
|
|
|
torso_y = info.angle;
|
|
|
|
torso_x = info.xAngle;
|
2020-10-17 13:23:01 -05:00
|
|
|
tonyboss->maximumTurn = TONYBOSS_TURN / 2;
|
2019-11-23 14:49:00 +01:00
|
|
|
|
2020-07-21 09:56:47 +02:00
|
|
|
if ((item->frameNumber - g_Level.Anims[item->animNumber].frameBase) == 28)
|
2020-05-14 18:39:17 +02:00
|
|
|
TriggerFireBall(item, T_ZAPP, NULL, item->roomNumber, item->pos.yRot, 0);
|
2019-11-23 14:49:00 +01:00
|
|
|
break;
|
|
|
|
|
2021-03-24 12:49:36 -05:00
|
|
|
case TONYBOSS_BIGBOOM:
|
2019-11-23 14:49:00 +01:00
|
|
|
tonyboss->maximumTurn = 0;
|
2020-07-21 09:56:47 +02:00
|
|
|
if ((item->frameNumber - g_Level.Anims[item->animNumber].frameBase) == 56)
|
2019-11-23 14:49:00 +01:00
|
|
|
{
|
|
|
|
item->itemFlags[3] = 2;
|
2021-03-24 12:49:36 -05:00
|
|
|
BossData.DrawExplode = true;
|
2019-11-23 14:49:00 +01:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (item->currentAnimState == TONYBOSS_ROCKZAPP || item->currentAnimState == TONYBOSS_ZAPP || item->currentAnimState == TONYBOSS_BIGBOOM)
|
|
|
|
{
|
2020-05-14 18:39:17 +02:00
|
|
|
byte r, g, b;
|
|
|
|
int bright;
|
2019-11-23 14:49:00 +01:00
|
|
|
|
2020-07-21 09:56:47 +02:00
|
|
|
bright = item->frameNumber - g_Level.Anims[item->animNumber].frameBase;
|
2019-11-23 14:49:00 +01:00
|
|
|
if (bright > 16)
|
|
|
|
{
|
2020-07-21 09:56:47 +02:00
|
|
|
bright = g_Level.Anims[item->animNumber].frameEnd - item->frameNumber;
|
2019-11-23 14:49:00 +01:00
|
|
|
if (bright > 16)
|
|
|
|
bright = 16;
|
|
|
|
}
|
|
|
|
|
|
|
|
rnd = GetRandomControl();
|
2020-10-17 13:23:01 -05:00
|
|
|
r = 31 - ((rnd / 16) & 3);
|
|
|
|
g = 24 - ((rnd / 64) & 3);
|
2019-11-23 14:49:00 +01:00
|
|
|
b = rnd & 7;
|
2020-10-17 13:23:01 -05:00
|
|
|
r = (r * bright) / 16;
|
|
|
|
g = (g * bright) / 16;
|
|
|
|
b = (b * bright) / 16;
|
2019-11-23 14:49:00 +01:00
|
|
|
|
|
|
|
pos1.x = pos1.y = pos1.z = 0;
|
|
|
|
GetJointAbsPosition(item, &pos1, 10);
|
2020-05-14 18:39:17 +02:00
|
|
|
TriggerDynamicLight(pos1.x, pos1.y, pos1.z, 12, r, g, b);
|
|
|
|
TriggerTonyFlame(itemNum, 14);
|
2019-11-23 14:49:00 +01:00
|
|
|
|
|
|
|
if (item->currentAnimState == TONYBOSS_ROCKZAPP || item->currentAnimState == TONYBOSS_BIGBOOM)
|
|
|
|
{
|
|
|
|
pos1.x = pos1.y = pos1.z = 0;
|
|
|
|
GetJointAbsPosition(item, &pos1, 13);
|
2020-05-14 18:39:17 +02:00
|
|
|
TriggerDynamicLight(pos1.x, pos1.y, pos1.z, 12, r, g, b);
|
|
|
|
TriggerTonyFlame(itemNum, 13);
|
2019-11-23 14:49:00 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-14 18:39:17 +02:00
|
|
|
if (BossData.ExplodeCount && item->hitPoints > 0)
|
2019-11-23 14:49:00 +01:00
|
|
|
{
|
2020-05-14 18:39:17 +02:00
|
|
|
ExplodeTonyBoss(item);
|
|
|
|
BossData.ExplodeCount++;
|
|
|
|
|
|
|
|
if (BossData.ExplodeCount > 64)
|
|
|
|
{
|
|
|
|
BossData.ExplodeCount = 0;
|
|
|
|
BossData.RingCount = 0;
|
|
|
|
}
|
2019-11-23 14:49:00 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
CreatureJoint(item, 0, torso_y >> 1);
|
|
|
|
CreatureJoint(item, 1, torso_x);
|
|
|
|
CreatureJoint(item, 2, torso_y >> 1);
|
|
|
|
CreatureAnimation(itemNum, angle, 0);
|
|
|
|
}
|
|
|
|
|
2020-05-14 18:39:17 +02:00
|
|
|
void S_DrawTonyBoss(ITEM_INFO* item)
|
2019-11-23 14:49:00 +01:00
|
|
|
{
|
2020-05-14 18:39:17 +02:00
|
|
|
DrawAnimatingItem(item);
|
2019-11-23 14:49:00 +01:00
|
|
|
}
|