TombEngine/TR5Main/Game/control/flipeffect.cpp

336 lines
6.8 KiB
C++
Raw Normal View History

#include "framework.h"
2021-12-22 16:23:57 +03:00
#include "Game/control/flipeffect.h"
2021-12-24 03:32:19 +03:00
2021-12-22 16:23:57 +03:00
#include "Game/camera.h"
#include "Game/collision/collide_room.h"
2021-12-24 03:32:19 +03:00
#include "Game/control/lot.h"
#include "Game/effects/hair.h"
2021-12-22 16:23:57 +03:00
#include "Game/effects/tomb4fx.h"
#include "Game/effects/weather.h"
#include "Game/effects/footprint.h"
#include "Game/effects/debris.h"
#include "Game/items.h"
2021-12-24 03:32:19 +03:00
#include "Game/Lara/lara.h"
#include "Game/Lara/lara_fire.h"
#include "Game/Lara/lara_helpers.h"
2021-12-24 03:32:19 +03:00
#include "Game/pickup/pickup.h"
#include "Sound/sound.h"
#include "Specific/level.h"
#include "Specific/setup.h"
#include "Objects/Generic/puzzles_keys.h"
#include "Objects/TR5/Emitter/tr5_spider_emitter.h"
#include "Objects/TR5/Object/tr5_pushableblock.h"
2021-09-25 11:27:47 +02:00
using std::function;
2021-08-30 18:03:21 +03:00
using namespace TEN::Effects::Footprints;
2021-09-15 14:24:03 +03:00
using namespace TEN::Effects::Environment;
2020-05-28 22:17:55 +02:00
int FlipEffect;
2021-09-15 14:45:20 +03:00
function<EffectFunction> effect_routines[NUM_FLIPEFFECTS] =
{
2021-08-26 16:11:04 +03:00
Turn180, //0
FloorShake, //1
2021-06-05 22:15:25 -05:00
PoseidonSFX, //2
LaraBubbles, //3
2021-08-26 16:11:04 +03:00
FinishLevel, //4
2021-06-05 22:15:25 -05:00
ActivateCamera, //5
ActivateKey, //6
RubbleFX, //7
SwapCrowbar, //8
2021-08-26 16:11:04 +03:00
Pickup, //9
PlaySoundEffect, //10
2021-06-05 22:15:25 -05:00
ExplosionFX, //11
2021-08-26 16:11:04 +03:00
LaraHandsFree, //12
Puzzle, //13
DrawRightPistol, //14
DrawLeftPistol, //15
ShootRightGun, //16
ShootLeftGun, //17
PushLoop, //18
PushEnd, //19
2021-09-15 14:24:03 +03:00
FlashOrange, //20
2021-08-26 16:11:04 +03:00
InvisibilityOn, //21
InvisibilityOff, //22
VoidEffect, //23
VoidEffect, //24
VoidEffect, //25
ResetHair, //26
VoidEffect, //27
2021-06-05 22:15:25 -05:00
SetFog, //28
2021-08-26 16:11:04 +03:00
VoidEffect, //29
2021-06-05 22:15:25 -05:00
LaraLocation, //30
ClearSpidersPatch, //31
AddLeftFootprint, //32
AddRightFootprint, //33
2021-08-26 16:11:04 +03:00
VoidEffect, //34
VoidEffect, //35
VoidEffect, //36
VoidEffect, //37
VoidEffect, //38
VoidEffect, //39
VoidEffect, //40
VoidEffect, //41
VoidEffect, //42
2021-06-05 22:15:25 -05:00
MeshSwapToPour, //43
MeshSwapFromPour, //44
LaraLocationPad, //45
KillActiveBaddies //46
};
2021-09-15 14:24:03 +03:00
void FlashOrange(ITEM_INFO* item)
{
FlipEffect = -1;
Weather.Flash(255, 128, 0, 0.03f);
}
2021-06-05 22:15:25 -05:00
void MeshSwapToPour(ITEM_INFO* item)
{
auto* lara = GetLaraInfo(item);
lara->MeshPtrs[LM_LHAND] = Objects[item->ItemFlags[2]].meshIndex + LM_LHAND;
2021-06-05 22:15:25 -05:00
}
void MeshSwapFromPour(ITEM_INFO* item)
{
auto* lara = GetLaraInfo(item);
lara->MeshPtrs[LM_LHAND] = Objects[ID_LARA_SKIN].meshIndex + LM_LHAND;
2021-06-05 22:15:25 -05:00
}
2021-08-26 16:11:04 +03:00
void Pickup(ITEM_INFO* item)
2020-06-15 00:32:58 -05:00
{
DoPickup(item);
2020-06-15 00:32:58 -05:00
}
2021-08-26 16:11:04 +03:00
void Puzzle(ITEM_INFO* item)
2020-07-23 15:29:02 -05:00
{
2021-11-03 03:49:57 +03:00
DoPuzzle();
2020-07-23 15:29:02 -05:00
}
void AddLeftFootprint(ITEM_INFO* item)
{
AddFootprint(item, false);
}
void AddRightFootprint(ITEM_INFO* item)
{
AddFootprint(item, true);
}
2021-08-26 16:11:04 +03:00
void ResetHair(ITEM_INFO* item)
{
InitialiseHair();
}
2021-08-26 16:11:04 +03:00
void InvisibilityOff(ITEM_INFO* item)
{
item->Status = ITEM_ACTIVE;
}
2021-08-26 16:11:04 +03:00
void InvisibilityOn(ITEM_INFO* item)
{
item->Status = ITEM_INVISIBLE;
}
2021-02-03 01:50:59 -03:00
void SetFog(ITEM_INFO* item)
{
FlipEffect = -1;
}
2021-08-26 16:11:04 +03:00
void DrawLeftPistol(ITEM_INFO* item)
{
auto* lara = GetLaraInfo(item);
if (lara->MeshPtrs[LM_LHAND] == Objects[ID_LARA_SKIN].meshIndex + LM_LHAND)
{
lara->MeshPtrs[LM_LHAND] = Objects[WeaponObjectMesh(item, LaraWeaponType::Pistol)].meshIndex + LM_LHAND;
lara->Control.Weapon.HolsterInfo.LeftHolster = HolsterSlot::Empty;
}
else
{
lara->MeshPtrs[LM_LHAND] = Objects[ID_LARA_SKIN].meshIndex + LM_LHAND;
lara->Control.Weapon.HolsterInfo.LeftHolster = HolsterSlotForWeapon(LaraWeaponType::Pistol);
}
}
2021-08-26 16:11:04 +03:00
void DrawRightPistol(ITEM_INFO* item)
{
auto* lara = GetLaraInfo(item);
if (lara->MeshPtrs[LM_RHAND] == Objects[ID_LARA_SKIN].meshIndex + LM_RHAND)
{
lara->MeshPtrs[LM_RHAND] = Objects[WeaponObjectMesh(item, LaraWeaponType::Pistol)].meshIndex + LM_RHAND;
lara->Control.Weapon.HolsterInfo.RightHolster = HolsterSlot::Empty;
}
else
{
lara->MeshPtrs[LM_RHAND] = Objects[ID_LARA_SKIN].meshIndex + LM_RHAND;
lara->Control.Weapon.HolsterInfo.RightHolster = HolsterSlotForWeapon(LaraWeaponType::Pistol);
}
}
2021-08-26 16:11:04 +03:00
void ShootLeftGun(ITEM_INFO* item)
{
auto* lara = GetLaraInfo(item);
lara->LeftArm.FlashGun = 3;
}
2021-08-26 16:11:04 +03:00
void ShootRightGun(ITEM_INFO* item)
{
auto* lara = GetLaraInfo(item);
lara->RightArm.FlashGun = 3;
}
2021-08-26 16:11:04 +03:00
void LaraHandsFree(ITEM_INFO* item)
{
auto* lara = GetLaraInfo(item);
lara->Control.HandStatus = HandStatus::Free;
}
2021-02-03 01:50:59 -03:00
void KillActiveBaddies(ITEM_INFO* item)
{
if (NextItemActive != NO_ITEM)
{
short itemNumber = NextItemActive;
do
2019-12-01 08:13:19 +01:00
{
auto* targetItem = &g_Level.Items[itemNumber];
if (Objects[targetItem->ObjectNumber].intelligent)
2019-12-01 08:13:19 +01:00
{
targetItem->Status = ITEM_INVISIBLE;
if (*(int*)&item != 0xABCDEF)
2019-12-01 08:13:19 +01:00
{
RemoveActiveItem(itemNumber);
DisableEntityAI(itemNumber);
targetItem->Flags |= IFLAG_INVISIBLE;
2019-12-01 08:13:19 +01:00
}
}
itemNumber = targetItem->NextActive;
} while (itemNumber != NO_ITEM);
2019-12-01 08:13:19 +01:00
}
FlipEffect = -1;
2019-12-01 08:13:19 +01:00
}
2021-02-03 01:50:59 -03:00
void LaraLocationPad(ITEM_INFO* item)
2019-12-01 08:13:19 +01:00
{
auto* lara = GetLaraInfo(item);
FlipEffect = -1;
lara->Location = TriggerTimer;
lara->LocationPad = TriggerTimer;
}
2021-02-03 01:50:59 -03:00
void LaraLocation(ITEM_INFO* item)
{
auto* lara = GetLaraInfo(item);
FlipEffect = -1;
lara->Location = TriggerTimer;
if (lara->HighestLocation < TriggerTimer)
lara->HighestLocation = TriggerTimer;
}
2021-02-03 01:50:59 -03:00
void ExplosionFX(ITEM_INFO* item)
{
SoundEffect(SFX_TR4_EXPLOSION1, NULL, 0);
Camera.bounce = -75;
FlipEffect = -1;
}
2021-02-03 01:50:59 -03:00
void SwapCrowbar(ITEM_INFO* item)
{
auto* lara = GetLaraInfo(item);
if (lara->MeshPtrs[LM_RHAND] == Objects[ID_LARA_SKIN].meshIndex + LM_RHAND)
lara->MeshPtrs[LM_RHAND] = Objects[ID_LARA_CROWBAR_ANIM].meshIndex + LM_RHAND;
else
lara->MeshPtrs[LM_RHAND] = Objects[ID_LARA_SKIN].meshIndex + LM_RHAND;
}
2021-02-03 01:50:59 -03:00
void ActivateKey(ITEM_INFO* item)
{
KeyTriggerActive = 1;
}
2021-02-03 01:50:59 -03:00
void ActivateCamera(ITEM_INFO* item)
{
KeyTriggerActive = 2;
}
2021-02-03 01:50:59 -03:00
void PoseidonSFX(ITEM_INFO* item)
{
SoundEffect(SFX_TR4_WATER_FLUSHES, NULL, 0);
FlipEffect = -1;
}
2021-02-03 01:50:59 -03:00
void RubbleFX(ITEM_INFO* item)
{
2021-09-15 14:24:03 +03:00
const auto itemList = FindAllItems(ID_EARTHQUAKE);
2021-02-07 17:12:41 -03:00
if (itemList.size() > 0)
{
auto* eq = &g_Level.Items[itemList[0]];
2021-02-07 17:12:41 -03:00
AddActiveItem(itemList[0]);
eq->Status = ITEM_ACTIVE;
eq->Flags |= IFLAG_ACTIVATION_MASK;
}
else
Camera.bounce = -150;
FlipEffect = -1;
}
2021-08-26 16:11:04 +03:00
void PlaySoundEffect(ITEM_INFO* item)
{
SoundEffect(TriggerTimer, NULL, 0);
FlipEffect = -1;
}
2021-08-26 16:11:04 +03:00
void FloorShake(ITEM_INFO* item)
{
int x = abs(item->Position.xPos - Camera.pos.x);
int y = abs(item->Position.yPos - Camera.pos.y);
int z = abs(item->Position.zPos - Camera.pos.z);
if (x < SECTOR(16) &&
y < SECTOR(16) &&
z < SECTOR(16))
{
Camera.bounce = 66 * ((pow(x, 2) + pow(y, 2) + pow(z, 2)) / CLICK(1) - pow(SECTOR(1), 2)) / pow(SECTOR(1), 2);
}
}
2021-08-26 16:11:04 +03:00
void Turn180(ITEM_INFO* item)
{
item->Position.yRot -= ANGLE(180.0f);
item->Position.xRot = -item->Position.xRot;
}
2021-08-26 16:11:04 +03:00
void FinishLevel(ITEM_INFO* item)
{
LevelComplete = CurrentLevel + 1;
}
2021-08-26 16:11:04 +03:00
void VoidEffect(ITEM_INFO* item)
{
}
2021-09-15 17:49:01 +03:00
void DoFlipEffect(int number, ITEM_INFO* item)
{
if (number != -1 && number < NUM_FLIPEFFECTS && effect_routines[number] != nullptr)
effect_routines[number](item);
}