mirror of
https://github.com/TombEngine/TombEngine.git
synced 2025-05-01 09:18:00 +03:00
Merge branch 'ten_beta' into states_tier_3
This commit is contained in:
commit
57e5ddf9cc
231 changed files with 6973 additions and 15537 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -6,6 +6,7 @@ TombEngine/Debug/
|
|||
TombEngine/Release
|
||||
TombEngine/Legacy Engine Objects
|
||||
x64/
|
||||
packages/
|
||||
.vs/
|
||||
*.dll
|
||||
*.dmp
|
||||
|
@ -23,4 +24,3 @@ x64/
|
|||
*.wav
|
||||
*.trc
|
||||
*.str
|
||||
packages/
|
||||
|
|
|
@ -1,108 +0,0 @@
|
|||
-- Inventory constants
|
||||
INV_OBJECT_UZIS = 0
|
||||
INV_OBJECT_PISTOLS = 1
|
||||
INV_OBJECT_SHOTGUN = 2
|
||||
INV_OBJECT_REVOLVER = 3
|
||||
INV_OBJECT_REVOLVER_LASER = 4
|
||||
INV_OBJECT_CROSSBOW = 5
|
||||
INV_OBJECT_CROSSBOW_LASER = 6
|
||||
INV_OBJECT_HK = 7
|
||||
INV_OBJECT_HK_LASER = 8
|
||||
INV_OBJECT_SHOTGUN_AMMO1 = 9
|
||||
INV_OBJECT_SHOTGUN_AMMO2 = 10
|
||||
INV_OBJECT_HK_AMMO1 = 13
|
||||
INV_OBJECT_CROSSBOW_AMMO1 = 15
|
||||
INV_OBJECT_CROSSBOW_AMMO2 = 16
|
||||
INV_OBJECT_REVOLVER_AMMO = 17
|
||||
INV_OBJECT_UZI_AMMO = 18
|
||||
INV_OBJECT_PISTOLS_AMMO = 19
|
||||
INV_OBJECT_LASERSIGHT = 20
|
||||
INV_OBJECT_SILENCER = 21
|
||||
INV_OBJECT_LARGE_MEDIPACK = 22
|
||||
INV_OBJECT_SMALL_MEDIPACK = 23
|
||||
INV_OBJECT_BINOCULARS = 24
|
||||
INV_OBJECT_FLARES = 25
|
||||
INV_OBJECT_TIMEX = 26
|
||||
INV_OBJECT_PUZZLE1 = 29
|
||||
INV_OBJECT_PUZZLE2 = 30
|
||||
INV_OBJECT_PUZZLE3 = 31
|
||||
INV_OBJECT_PUZZLE4 = 32
|
||||
INV_OBJECT_PUZZLE5 = 33
|
||||
INV_OBJECT_PUZZLE6 = 34
|
||||
INV_OBJECT_PUZZLE7 = 35
|
||||
INV_OBJECT_PUZZLE8 = 36
|
||||
INV_OBJECT_PUZZLE1_COMBO1 = 37
|
||||
INV_OBJECT_PUZZLE1_COMBO2 = 38
|
||||
INV_OBJECT_PUZZLE2_COMBO1 = 39
|
||||
INV_OBJECT_PUZZLE2_COMBO2 = 40
|
||||
INV_OBJECT_PUZZLE3_COMBO1 = 41
|
||||
INV_OBJECT_PUZZLE3_COMBO2 = 42
|
||||
INV_OBJECT_PUZZLE4_COMBO1 = 43
|
||||
INV_OBJECT_PUZZLE4_COMBO2 = 44
|
||||
INV_OBJECT_PUZZLE5_COMBO1 = 45
|
||||
INV_OBJECT_PUZZLE5_COMBO2 = 46
|
||||
INV_OBJECT_PUZZLE6_COMBO1 = 47
|
||||
INV_OBJECT_PUZZLE6_COMBO2 = 48
|
||||
INV_OBJECT_PUZZLE7_COMBO1 = 49
|
||||
INV_OBJECT_PUZZLE7_COMBO2 = 50
|
||||
INV_OBJECT_PUZZLE8_COMBO1 = 51
|
||||
INV_OBJECT_PUZZLE8_COMBO2 = 52
|
||||
INV_OBJECT_KEY1 = 53
|
||||
INV_OBJECT_KEY2 = 54
|
||||
INV_OBJECT_KEY3 = 55
|
||||
INV_OBJECT_KEY4 = 56
|
||||
INV_OBJECT_KEY5 = 57
|
||||
INV_OBJECT_KEY6 = 58
|
||||
INV_OBJECT_KEY7 = 59
|
||||
INV_OBJECT_KEY8 = 60
|
||||
INV_OBJECT_KEY1_COMBO1 = 61
|
||||
INV_OBJECT_KEY1_COMBO2 = 62
|
||||
INV_OBJECT_KEY2_COMBO1 = 63
|
||||
INV_OBJECT_KEY2_COMBO2 = 64
|
||||
INV_OBJECT_KEY3_COMBO1 = 65
|
||||
INV_OBJECT_KEY3_COMBO2 = 66
|
||||
INV_OBJECT_KEY4_COMBO1 = 67
|
||||
INV_OBJECT_KEY4_COMBO2 = 68
|
||||
INV_OBJECT_KEY5_COMBO1 = 69
|
||||
INV_OBJECT_KEY5_COMBO2 = 70
|
||||
INV_OBJECT_KEY6_COMBO1 = 71
|
||||
INV_OBJECT_KEY6_COMBO2 = 72
|
||||
INV_OBJECT_KEY7_COMBO1 = 73
|
||||
INV_OBJECT_KEY7_COMBO2 = 74
|
||||
INV_OBJECT_KEY8_COMBO1 = 75
|
||||
INV_OBJECT_KEY8_COMBO2 = 76
|
||||
INV_OBJECT_PICKUP1 = 77
|
||||
INV_OBJECT_PICKUP2 = 78
|
||||
INV_OBJECT_PICKUP3 = 79
|
||||
INV_OBJECT_PICKUP4 = 80
|
||||
INV_OBJECT_PICKUP1_COMBO1 = 81
|
||||
INV_OBJECT_PICKUP1_COMBO2 = 82
|
||||
INV_OBJECT_PICKUP2_COMBO1 = 83
|
||||
INV_OBJECT_PICKUP2_COMBO2 = 84
|
||||
INV_OBJECT_PICKUP3_COMBO1 = 85
|
||||
INV_OBJECT_PICKUP3_COMBO2 = 86
|
||||
INV_OBJECT_PICKUP4_COMBO1 = 87
|
||||
INV_OBJECT_PICKUP4_COMBO2 = 88
|
||||
INV_OBJECT_BRUNING_TORCH = 89
|
||||
INV_OBJECT_CROWBAR = 90
|
||||
INV_OBJECT_EXAMINE1 = 91
|
||||
INV_OBJECT_EXAMINE2 = 92
|
||||
INV_OBJECT_EXAMINE3 = 93
|
||||
INV_OBJECT_WETCLOTH1 = 93
|
||||
INV_OBJECT_GRAPPLING_GUN = 95
|
||||
INV_OBJECT_GRAPPLING_AMMO = 96
|
||||
INV_OBJECT_WETCLOTH2 = 97
|
||||
INV_OBJECT_BOTTLE = 98
|
||||
|
||||
-- Item constants
|
||||
ITEM_currentAnimState = 0
|
||||
ITEM_goalAnimState = 1
|
||||
ITEM_REQUIRED_ANIM_STATE = 2
|
||||
ITEM_frameNumber = 3
|
||||
ITEM_animNumber = 4
|
||||
ITEM_hitPoints = 5
|
||||
ITEM_HIT_STATUS = 6
|
||||
ITEM_GRAVITY_STATUS = 7
|
||||
ITEM_COLLIDABLE = 8
|
||||
ITEM_POISONED = 9
|
||||
ITEM_roomNumber = 10
|
|
@ -490,7 +490,7 @@ local strings = {
|
|||
""
|
||||
},
|
||||
grenade_launcher_ammo1 = {
|
||||
"Grenadegun (Normal Ammo)",
|
||||
"Grenade Gun Normal Ammo",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
|
@ -500,7 +500,7 @@ local strings = {
|
|||
""
|
||||
},
|
||||
grenade_launcher_ammo2 = {
|
||||
"Grenadegun (Super Ammo)",
|
||||
"Grenade Gun Super Ammo",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
|
@ -510,7 +510,7 @@ local strings = {
|
|||
""
|
||||
},
|
||||
grenade_launcher_ammo3 = {
|
||||
"Grenadegun (Flash Ammo)",
|
||||
"Grenade Gun Flash Ammo",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
|
@ -519,8 +519,8 @@ local strings = {
|
|||
"",
|
||||
""
|
||||
},
|
||||
harpoon_item = {
|
||||
"Harpoon Launcher",
|
||||
harpoon_gun = {
|
||||
"Harpoon Gun",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
|
@ -530,7 +530,7 @@ local strings = {
|
|||
""
|
||||
},
|
||||
harpoon_ammo = {
|
||||
"Harpoon Launcher Ammo",
|
||||
"Harpoon Gun Ammo",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
|
@ -780,7 +780,7 @@ local strings = {
|
|||
""
|
||||
},
|
||||
savegame_timestamp = {
|
||||
"%d Days %d:%d:%d",
|
||||
"%02d Days %02d:%02d:%02d",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
|
@ -889,6 +889,16 @@ local strings = {
|
|||
"",
|
||||
""
|
||||
},
|
||||
options = {
|
||||
"Options",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
""
|
||||
},
|
||||
sound = {
|
||||
"Sound settings",
|
||||
"",
|
||||
|
|
|
@ -751,9 +751,9 @@ void LaraAboveWater(ItemInfo* item, CollisionInfo* coll)
|
|||
coll->Setup.EnableSpasm = true;
|
||||
|
||||
coll->Setup.OldPosition = item->Pose.Position;
|
||||
coll->Setup.OldState = item->Animation.ActiveState;
|
||||
coll->Setup.OldAnimNumber = item->Animation.AnimNumber;
|
||||
coll->Setup.OldFrameNumber = item->Animation.FrameNumber;
|
||||
coll->Setup.OldState = item->Animation.ActiveState;
|
||||
|
||||
if (TrInput & IN_LOOK && lara->Control.CanLook &&
|
||||
lara->ExtraAnim == NO_ITEM)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#pragma once
|
||||
#include "Game/control/control.h"
|
||||
#include "Game/Lara/lara_struct.h"
|
||||
|
||||
struct ItemInfo;
|
||||
|
@ -67,14 +68,14 @@ constexpr auto LARA_DEATH_VELOCITY = 155;
|
|||
constexpr auto LARA_DIVE_DEATH_VELOCITY = 134;
|
||||
constexpr auto LARA_TERMINAL_VELOCITY = CLICK(10);
|
||||
|
||||
constexpr auto LARA_POSITION_ADJUST_MAX_TIME = 30 * 3; // 30 frames * 3 = 3 seconds allowed for position adjustment.
|
||||
constexpr auto LARA_POSE_TIME = 30 * 30; // 30 frames * 30 = 30 seconds to AFK pose.
|
||||
constexpr auto LARA_POSITION_ADJUST_MAX_TIME = FPS * 3; // 30 frames * 3 = 3 seconds allowed for position adjustment.
|
||||
constexpr auto LARA_POSE_TIME = FPS * 30; // 30 frames * 30 = 30 seconds to AFK pose.
|
||||
constexpr auto LARA_RUN_JUMP_TIME = 22; // Frames to count before a running jump is possible.
|
||||
|
||||
constexpr auto LARA_HEALTH_MAX = 1000.0f;
|
||||
constexpr auto LARA_AIR_MAX = 1800.0f;
|
||||
constexpr auto LARA_SPRINT_ENERGY_MAX = 120.0f;
|
||||
constexpr auto LARA_POISON_POTENCY_MAX = 16.0f;
|
||||
constexpr auto LARA_POISON_POTENCY_MAX = 32.0f;
|
||||
|
||||
extern LaraInfo Lara;
|
||||
extern ItemInfo* LaraItem;
|
||||
|
|
|
@ -1419,7 +1419,7 @@ void lara_as_death(ItemInfo* item, CollisionInfo* coll)
|
|||
BinocularRange = 0;
|
||||
LaserSight = false;
|
||||
AlterFOV(ANGLE(80.0f));
|
||||
item->MeshBits = -1;
|
||||
item->MeshBits = ALL_JOINT_BITS;
|
||||
lara->Inventory.IsBusy = false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -408,7 +408,7 @@ void lara_as_climb_stepoff_right(ItemInfo* item, CollisionInfo* coll)
|
|||
|
||||
short GetClimbFlags(int x, int y, int z, short roomNumber)
|
||||
{
|
||||
return GetClimbFlags(GetFloor(x, y, z, &roomNumber));
|
||||
return GetClimbFlags(GetCollision(x, y, z, roomNumber).BottomBlock);
|
||||
}
|
||||
|
||||
short GetClimbFlags(FloorInfo* floor)
|
||||
|
|
|
@ -64,7 +64,7 @@ bool LaraDeflectEdgeJump(ItemInfo* item, CollisionInfo* coll)
|
|||
SetAnimation(item, LA_LAND);
|
||||
LaraSnapToHeight(item, coll);
|
||||
}
|
||||
else if (abs(item->Animation.Velocity) > CLICK(0.5f))
|
||||
else if (abs(item->Animation.Velocity) > 47) // TODO: Demagic. This is Lara's running velocity. Jumps have a minimum of 50.
|
||||
SetAnimation(item, LA_JUMP_WALL_SMASH_START, 1);
|
||||
|
||||
item->Animation.Velocity /= 4;
|
||||
|
@ -670,10 +670,10 @@ bool TestLaraHitCeiling(CollisionInfo* coll)
|
|||
|
||||
void SetLaraHitCeiling(ItemInfo* item, CollisionInfo* coll)
|
||||
{
|
||||
item->Pose.Position = coll->Setup.OldPosition;
|
||||
item->Animation.Airborne = false;
|
||||
item->Animation.Velocity = 0;
|
||||
item->Animation.VerticalVelocity = 0;
|
||||
item->Pose.Position = coll->Setup.OldPosition;
|
||||
}
|
||||
|
||||
bool TestLaraObjectCollision(ItemInfo* item, short angle, int distance, int height, int side)
|
||||
|
|
|
@ -53,6 +53,10 @@ void lara_as_crouch_idle(ItemInfo* item, CollisionInfo* coll)
|
|||
if (TrInput & IN_LOOK)
|
||||
LookUpDown(item);
|
||||
|
||||
// HACK.
|
||||
if (BinocularOn)
|
||||
return;
|
||||
|
||||
if (TrInput & IN_LEFT)
|
||||
lara->Control.TurnRate.y = -LARA_CRAWL_TURN_MAX;
|
||||
else if (TrInput & IN_RIGHT)
|
||||
|
@ -397,6 +401,10 @@ void lara_as_crawl_idle(ItemInfo* item, CollisionInfo* coll)
|
|||
if (TrInput & IN_LOOK)
|
||||
LookUpDown(item);
|
||||
|
||||
// HACK.
|
||||
if (BinocularOn)
|
||||
return;
|
||||
|
||||
if (TrInput & IN_LEFT)
|
||||
lara->Control.TurnRate.y = -LARA_CRAWL_TURN_MAX;
|
||||
else if (TrInput & IN_RIGHT)
|
||||
|
|
|
@ -66,7 +66,7 @@ WeaponInfo Weapons[(int)LaraWeaponType::NumWeapons] =
|
|||
9,
|
||||
3,
|
||||
0,
|
||||
SFX_TR4_LARA_FIRE,
|
||||
SFX_TR4_PISTOL_FIRE,
|
||||
0
|
||||
},
|
||||
|
||||
|
@ -83,7 +83,7 @@ WeaponInfo Weapons[(int)LaraWeaponType::NumWeapons] =
|
|||
16,
|
||||
3,
|
||||
0,
|
||||
SFX_TR4_DESSERT_EAGLE_FIRE,
|
||||
SFX_TR4_REVOLVER_FIRE,
|
||||
0
|
||||
},
|
||||
|
||||
|
@ -100,7 +100,7 @@ WeaponInfo Weapons[(int)LaraWeaponType::NumWeapons] =
|
|||
3,
|
||||
3,
|
||||
0,
|
||||
SFX_TR4_LARA_UZI_FIRE,
|
||||
SFX_TR4_UZI_FIRE,
|
||||
0
|
||||
},
|
||||
|
||||
|
@ -117,7 +117,7 @@ WeaponInfo Weapons[(int)LaraWeaponType::NumWeapons] =
|
|||
9,
|
||||
3,
|
||||
9,
|
||||
SFX_TR4_LARA_SHOTGUN,
|
||||
SFX_TR4_SHOTGUN_FIRE,
|
||||
0
|
||||
},
|
||||
|
||||
|
@ -151,7 +151,7 @@ WeaponInfo Weapons[(int)LaraWeaponType::NumWeapons] =
|
|||
0,
|
||||
2,
|
||||
9,
|
||||
SFX_TR4_LARA_CROSSBOW,
|
||||
SFX_TR4_CROSSBOW_FIRE,
|
||||
20
|
||||
},
|
||||
|
||||
|
@ -185,7 +185,7 @@ WeaponInfo Weapons[(int)LaraWeaponType::NumWeapons] =
|
|||
0,
|
||||
2,
|
||||
0,
|
||||
SFX_TR4_LARA_UZI_FIRE,
|
||||
SFX_TR4_UZI_FIRE,
|
||||
0
|
||||
},
|
||||
|
||||
|
@ -253,7 +253,7 @@ WeaponInfo Weapons[(int)LaraWeaponType::NumWeapons] =
|
|||
0,
|
||||
0,
|
||||
0,
|
||||
SFX_TR4_LARA_UZI_FIRE,
|
||||
SFX_TR4_UZI_FIRE,
|
||||
0
|
||||
}
|
||||
};
|
||||
|
@ -589,7 +589,6 @@ void LaraGun(ItemInfo* laraItem)
|
|||
case LaraWeaponType::Pistol:
|
||||
case LaraWeaponType::Uzi:
|
||||
PistolHandler(laraItem, lara->Control.Weapon.GunType);
|
||||
|
||||
break;
|
||||
|
||||
case LaraWeaponType::Shotgun:
|
||||
|
@ -722,7 +721,7 @@ GAME_OBJECT_ID WeaponObjectMesh(ItemInfo* laraItem, LaraWeaponType weaponType)
|
|||
switch (weaponType)
|
||||
{
|
||||
case LaraWeaponType::Revolver:
|
||||
return (lara->Weapons[(int)LaraWeaponType::Revolver].HasLasersight == true ? ID_LARA_REVOLVER_LASER : ID_REVOLVER_ANIM);
|
||||
return (lara->Weapons[(int)LaraWeaponType::Revolver].HasLasersight ? ID_LARA_REVOLVER_LASER : ID_REVOLVER_ANIM);
|
||||
|
||||
case LaraWeaponType::Uzi:
|
||||
return ID_UZI_ANIM;
|
||||
|
@ -734,7 +733,7 @@ GAME_OBJECT_ID WeaponObjectMesh(ItemInfo* laraItem, LaraWeaponType weaponType)
|
|||
return ID_HK_ANIM;
|
||||
|
||||
case LaraWeaponType::Crossbow:
|
||||
return (lara->Weapons[(int)LaraWeaponType::Crossbow].HasLasersight == true ? ID_LARA_CROSSBOW_LASER : ID_CROSSBOW_ANIM);
|
||||
return (lara->Weapons[(int)LaraWeaponType::Crossbow].HasLasersight ? ID_LARA_CROSSBOW_LASER : ID_CROSSBOW_ANIM);
|
||||
|
||||
case LaraWeaponType::GrenadeLauncher:
|
||||
return ID_GRENADE_ANIM;
|
||||
|
@ -775,7 +774,7 @@ void HitTarget(ItemInfo* laraItem, ItemInfo* target, GameVector* hitPos, int dam
|
|||
lara->Control.Weapon.GunType == LaraWeaponType::Uzi))
|
||||
{
|
||||
// Baddy2 gun hitting sword
|
||||
SoundEffect(SFX_TR4_BAD_SWORD_RICO, &target->Pose);
|
||||
SoundEffect(SFX_TR4_BADDY_SWORD_RICOCHET, &target->Pose);
|
||||
TriggerRicochetSpark(hitPos, laraItem->Pose.Orientation.y, 3, 0);
|
||||
return;
|
||||
}
|
||||
|
@ -794,7 +793,7 @@ void HitTarget(ItemInfo* laraItem, ItemInfo* target, GameVector* hitPos, int dam
|
|||
if (target->ObjectNumber == ID_ROMAN_GOD1 ||
|
||||
target->ObjectNumber == ID_ROMAN_GOD2)
|
||||
{
|
||||
SoundEffect(SFX_TR5_SWORD_GOD_HITMETAL, &target->Pose);
|
||||
SoundEffect(SFX_TR5_SWORD_GOD_HIT_METAL, &target->Pose);
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -815,6 +814,7 @@ void HitTarget(ItemInfo* laraItem, ItemInfo* target, GameVector* hitPos, int dam
|
|||
target->HitPoints = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!target->LuaCallbackOnHitName.empty())
|
||||
{
|
||||
short index = g_GameScriptEntities->GetIndexByName(target->LuaName);
|
||||
|
@ -897,7 +897,7 @@ FireWeaponType FireWeapon(LaraWeaponType weaponType, ItemInfo* target, ItemInfo*
|
|||
|
||||
// TODO: enable it when the slot is created !
|
||||
/*
|
||||
if (target->objectNumber == ID_TRIBEBOSS)
|
||||
if (target->ObjectNumber == ID_TRIBEBOSS)
|
||||
{
|
||||
long dx, dy, dz;
|
||||
|
||||
|
@ -906,27 +906,27 @@ FireWeaponType FireWeapon(LaraWeaponType weaponType, ItemInfo* target, ItemInfo*
|
|||
dz = (vDest.z - vSrc.z) >> 5;
|
||||
FindClosestShieldPoint(vDest.x - dx, vDest.y - dy, vDest.z - dz, target);
|
||||
}
|
||||
else if (target->objectNumber == ID_ARMY_WINSTON || target->objectNumber == ID_LONDONBOSS) //Don't want blood on Winston - never get the stains out
|
||||
else if (target->ObjectNumber == ID_ARMY_WINSTON || target->ObjectNumber == ID_LONDONBOSS) //Don't want blood on Winston - never get the stains out
|
||||
{
|
||||
short ricochet_angle;
|
||||
target->hitStatus = true; //need to do this to maintain defence state
|
||||
target->HitStatus = true; //need to do this to maintain defence state
|
||||
target->HitPoints--;
|
||||
ricochet_angle = (mGetAngle(lara->pos.Position.z, lara->pos.Position.x, target->pos.Position.z, target->pos.Position.x) >> 4) & 4095;
|
||||
ricochet_angle = (mGetAngle(lara->Pose.Position.z, lara->Pose.Position.x, target->Pose.Position.z, target->Pose.Position.x) >> 4) & 4095;
|
||||
TriggerRicochetSparks(&vDest, ricochet_angle, 16, 0);
|
||||
SoundEffect(SFX_TR4_LARA_RICOCHET, &target->pos); // play RICOCHET Sample
|
||||
SoundEffect(SFX_TR4_WEAPON_RICOCHET, &target->Pose); // play RICOCHET Sample
|
||||
}
|
||||
else if (target->objectNumber == ID_SHIVA) //So must be Shiva
|
||||
else if (target->ObjectNumber == ID_SHIVA) //So must be Shiva
|
||||
{
|
||||
z = target->pos.Position.z - lara_item->pos.Position.z;
|
||||
x = target->pos.Position.x - lara_item->pos.Position.x;
|
||||
angle = 0x8000 + phd_atan(z, x) - target->pos.Orientation.y;
|
||||
z = target->Pose.Position.z - lara_item->Pose.Position.z;
|
||||
x = target->Pose.Position.x - lara_item->Pose.Position.x;
|
||||
angle = 0x8000 + phd_atan(z, x) - target->Pose.Orientation.y;
|
||||
|
||||
if ((target->ActiveState > 1 && target->ActiveState < 5) && angle < 0x4000 && angle > -0x4000)
|
||||
{
|
||||
target->hitStatus = true; //need to do this to maintain defence state
|
||||
ricochet_angle = (mGetAngle(lara->pos.Position.z, lara->pos.Position.x, target->pos.Position.z, target->pos.Position.x) >> 4) & 4095;
|
||||
target->HitStatus = true; //need to do this to maintain defence state
|
||||
ricochet_angle = (mGetAngle(lara->Pose.Position.z, lara->Pose.Position.x, target->Pose.Position.z, target->Pose.Position.x) >> 4) & 4095;
|
||||
TriggerRicochetSparks(&vDest, ricochet_angle, 16, 0);
|
||||
SoundEffect(SFX_TR4_LARA_RICOCHET, &target->pos); // play RICOCHET Sample
|
||||
SoundEffect(SFX_TR4_WEAPON_RICOCHET, &target->Pose); // play RICOCHET Sample
|
||||
}
|
||||
else //Shiva's not in defence mode or has its back to Lara
|
||||
HitTarget(target, &vDest, weapon->damage, 0);
|
||||
|
@ -980,7 +980,8 @@ void LaraTargetInfo(ItemInfo* laraItem, WeaponInfo* weaponInfo)
|
|||
laraItem->Pose.Position.x,
|
||||
muzzleOffset.y,
|
||||
laraItem->Pose.Position.z,
|
||||
laraItem->RoomNumber);
|
||||
laraItem->RoomNumber
|
||||
);
|
||||
|
||||
auto targetPoint = GameVector();
|
||||
FindTargetPoint(lara->TargetEntity, &targetPoint);
|
||||
|
@ -1050,7 +1051,8 @@ void LaraGetNewTarget(ItemInfo* laraItem, WeaponInfo* weaponInfo)
|
|||
laraItem->Pose.Position.x,
|
||||
muzzleOffset.y,
|
||||
laraItem->Pose.Position.z,
|
||||
laraItem->RoomNumber);
|
||||
laraItem->RoomNumber
|
||||
);
|
||||
|
||||
ItemInfo* bestItem = nullptr;
|
||||
short bestYrot = MAXSHORT;
|
||||
|
|
|
@ -22,12 +22,12 @@ struct WeaponInfo
|
|||
short ShotAccuracy;
|
||||
int GunHeight;
|
||||
short TargetDist;
|
||||
byte Damage;
|
||||
byte RecoilFrame;
|
||||
byte FlashTime;
|
||||
byte DrawFrame;
|
||||
int Damage;
|
||||
int RecoilFrame;
|
||||
int FlashTime;
|
||||
int DrawFrame;
|
||||
short SampleNum;
|
||||
byte ExplosiveDamage;
|
||||
int ExplosiveDamage;
|
||||
};
|
||||
|
||||
enum WeaponState
|
||||
|
|
|
@ -31,7 +31,7 @@ void FlareControl(short itemNumber)
|
|||
|
||||
if (flareItem->Animation.VerticalVelocity)
|
||||
{
|
||||
flareItem->Pose.Orientation.x += ANGLE(3.0f);
|
||||
flareItem->Pose.Orientation.x -= ANGLE(5.0f);
|
||||
flareItem->Pose.Orientation.z += ANGLE(5.0f);
|
||||
}
|
||||
else
|
||||
|
@ -40,13 +40,14 @@ void FlareControl(short itemNumber)
|
|||
flareItem->Pose.Orientation.z = 0;
|
||||
}
|
||||
|
||||
auto velocity = Vector3Int(
|
||||
flareItem->Animation.Velocity * phd_sin(flareItem->Pose.Orientation.y),
|
||||
flareItem->Animation.VerticalVelocity,
|
||||
flareItem->Animation.Velocity * phd_cos(flareItem->Pose.Orientation.y)
|
||||
);
|
||||
|
||||
auto oldPos = flareItem->Pose.Position;
|
||||
|
||||
int xVel = flareItem->Animation.Velocity * phd_sin(flareItem->Pose.Orientation.y);
|
||||
int zVel = flareItem->Animation.Velocity * phd_cos(flareItem->Pose.Orientation.y);
|
||||
|
||||
flareItem->Pose.Position.x += xVel;
|
||||
flareItem->Pose.Position.z += zVel;
|
||||
flareItem->Pose.Position += Vector3Int(velocity.x, 0, velocity.z);
|
||||
|
||||
if (TestEnvironment(ENV_FLAG_WATER, flareItem) ||
|
||||
TestEnvironment(ENV_FLAG_SWAMP, flareItem))
|
||||
|
@ -58,8 +59,7 @@ void FlareControl(short itemNumber)
|
|||
flareItem->Animation.VerticalVelocity += 6;
|
||||
|
||||
flareItem->Pose.Position.y += flareItem->Animation.VerticalVelocity;
|
||||
|
||||
DoProjectileDynamics(itemNumber, oldPos.x, oldPos.y, oldPos.z, xVel, flareItem->Animation.VerticalVelocity, zVel);
|
||||
DoProjectileDynamics(itemNumber, oldPos.x, oldPos.y, oldPos.z, velocity.x, velocity.y, velocity.z);
|
||||
|
||||
int& life = flareItem->Data;
|
||||
life &= 0x7FFF;
|
||||
|
@ -244,7 +244,7 @@ void DrawFlare(ItemInfo* laraItem)
|
|||
{
|
||||
if (armFrame == 72)
|
||||
{
|
||||
SoundEffect(SFX_TR4_OBJ_GEM_SMASH, &laraItem->Pose, (SoundEnvironment)TestEnvironment(ENV_FLAG_WATER, laraItem));
|
||||
SoundEffect(SFX_TR4_FLARE_IGNITE_DRY, &laraItem->Pose, TestEnvironment(ENV_FLAG_WATER, laraItem) ? SoundEnvironment::Water : SoundEnvironment::Land);
|
||||
lara->Flare.Life = 1;
|
||||
}
|
||||
|
||||
|
@ -291,7 +291,6 @@ void CreateFlare(ItemInfo* laraItem, GAME_OBJECT_ID objectNumber, bool thrown)
|
|||
if (itemNumber != NO_ITEM)
|
||||
{
|
||||
auto* flareItem = &g_Level.Items[itemNumber];
|
||||
bool flag = false;
|
||||
|
||||
flareItem->ObjectNumber = objectNumber;
|
||||
flareItem->RoomNumber = laraItem->RoomNumber;
|
||||
|
@ -303,12 +302,13 @@ void CreateFlare(ItemInfo* laraItem, GAME_OBJECT_ID objectNumber, bool thrown)
|
|||
|
||||
int floorHeight = GetCollision(pos.x, pos.y, pos.z, laraItem->RoomNumber).Position.Floor;
|
||||
auto collided = GetCollidedObjects(flareItem, 0, true, CollidedItems, CollidedMeshes, true);
|
||||
bool landed = false;
|
||||
if (floorHeight < pos.y || collided)
|
||||
{
|
||||
flag = true;
|
||||
flareItem->Pose.Orientation.y = laraItem->Pose.Orientation.y + ANGLE(180.0f);
|
||||
landed = true;
|
||||
flareItem->Pose.Position.x = laraItem->Pose.Position.x + 320 * phd_sin(flareItem->Pose.Orientation.y);
|
||||
flareItem->Pose.Position.z = laraItem->Pose.Position.z + 320 * phd_cos(flareItem->Pose.Orientation.y);
|
||||
flareItem->Pose.Orientation.y = laraItem->Pose.Orientation.y + ANGLE(180.0f);
|
||||
flareItem->RoomNumber = laraItem->RoomNumber;
|
||||
}
|
||||
else
|
||||
|
@ -338,7 +338,7 @@ void CreateFlare(ItemInfo* laraItem, GAME_OBJECT_ID objectNumber, bool thrown)
|
|||
flareItem->Animation.VerticalVelocity = laraItem->Animation.VerticalVelocity + 50;
|
||||
}
|
||||
|
||||
if (flag)
|
||||
if (landed)
|
||||
flareItem->Animation.Velocity /= 2;
|
||||
|
||||
if (objectNumber == ID_FLARE_ITEM)
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
#pragma once
|
||||
#include "Game/control/control.h"
|
||||
|
||||
struct ItemInfo;
|
||||
struct CollisionInfo;
|
||||
struct Vector3Int;
|
||||
enum GAME_OBJECT_ID : short;
|
||||
|
||||
constexpr auto FLARE_LIFE_MAX = 60 * 30; // 60 * 30 frames = 60 seconds.
|
||||
constexpr auto FLARE_LIFE_MAX = 60 * FPS; // 60 * 30 frames = 60 seconds.
|
||||
|
||||
void FlareControl(short itemNumber);
|
||||
void ReadyFlare(ItemInfo* laraItem);
|
||||
|
|
|
@ -499,7 +499,7 @@ void UpdateLaraSubsuitAngles(ItemInfo* item)
|
|||
auto mul1 = (float)abs(lara->Control.Subsuit.Velocity[0]) / SECTOR(8);
|
||||
auto mul2 = (float)abs(lara->Control.Subsuit.Velocity[1]) / SECTOR(8);
|
||||
auto vol = ((mul1 + mul2) * 5.0f) + 0.5f;
|
||||
SoundEffect(SFX_TR5_DIVE_SUIT_ENGINE, &item->Pose, SoundEnvironment::Water, 1.0f + (mul1 + mul2), vol);
|
||||
SoundEffect(SFX_TR5_VEHICLE_DIVESUIT_ENGINE, &item->Pose, SoundEnvironment::Water, 1.0f + (mul1 + mul2), vol);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -664,9 +664,9 @@ void SetContextWaterClimbOut(ItemInfo* item, CollisionInfo* coll, WaterClimbOutT
|
|||
|
||||
void SetLaraLand(ItemInfo* item, CollisionInfo* coll)
|
||||
{
|
||||
//item->Airborne = false; // TODO: Removing this avoids an unusual landing bug Core had worked around in an obscure way. I hope to find a proper solution. @Sezz 2022.02.18
|
||||
item->Animation.Velocity = 0;
|
||||
item->Animation.VerticalVelocity = 0;
|
||||
//item->Airborne = false; // TODO: Removing this avoids an unusual landing bug Core had worked around in an obscure way. I hope to find a proper solution. @Sezz 2022.02.18
|
||||
|
||||
LaraSnapToHeight(item, coll);
|
||||
}
|
||||
|
@ -674,15 +674,15 @@ void SetLaraLand(ItemInfo* item, CollisionInfo* coll)
|
|||
void SetLaraFallAnimation(ItemInfo* item)
|
||||
{
|
||||
SetAnimation(item, LA_FALL_START);
|
||||
item->Animation.VerticalVelocity = 0;
|
||||
item->Animation.Airborne = true;
|
||||
item->Animation.VerticalVelocity = 0;
|
||||
}
|
||||
|
||||
void SetLaraFallBackAnimation(ItemInfo* item)
|
||||
{
|
||||
SetAnimation(item, LA_FALL_BACK);
|
||||
item->Animation.VerticalVelocity = 0;
|
||||
item->Animation.Airborne = true;
|
||||
item->Animation.VerticalVelocity = 0;
|
||||
}
|
||||
|
||||
void SetLaraMonkeyFallAnimation(ItemInfo* item)
|
||||
|
@ -750,7 +750,9 @@ void SetLaraSlideAnimation(ItemInfo* item, CollisionInfo* coll)
|
|||
item->Pose.Orientation.y = angle;
|
||||
}
|
||||
|
||||
LaraSnapToHeight(item, coll);
|
||||
lara->Control.MoveAngle = angle;
|
||||
lara->Control.TurnRate.y = 0;
|
||||
oldAngle = angle;
|
||||
}
|
||||
|
||||
|
@ -828,11 +830,11 @@ void SetLaraCornerAnimation(ItemInfo* item, CollisionInfo* coll, bool flip)
|
|||
if (item->HitPoints <= 0)
|
||||
{
|
||||
SetAnimation(item, LA_FALL_START);
|
||||
item->Pose.Position.y += CLICK(1);
|
||||
item->Pose.Orientation.y += lara->NextCornerPos.Orientation.y / 2;
|
||||
item->Animation.Airborne = true;
|
||||
item->Animation.Velocity = 2;
|
||||
item->Animation.VerticalVelocity = 1;
|
||||
item->Pose.Position.y += CLICK(1);
|
||||
item->Pose.Orientation.y += lara->NextCornerPos.Orientation.y / 2;
|
||||
lara->Control.HandStatus = HandStatus::Free;
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -809,7 +809,7 @@ void lara_as_swan_dive(ItemInfo* item, CollisionInfo* coll)
|
|||
g_GameFlow->HasCrawlspaceSwandive())
|
||||
{
|
||||
item->Animation.TargetState = LS_CROUCH_IDLE;
|
||||
TranslateItem(item, coll->Setup.ForwardAngle, CLICK(0.5f), 0, 0); // HACK: Move forward to avoid standing up or falling out on an edge.
|
||||
TranslateItem(item, coll->Setup.ForwardAngle, CLICK(0.5f)); // HACK: Move forward to avoid standing up or falling out on an edge.
|
||||
}
|
||||
else USE_FEATURE_IF_CPP20([[likely]])
|
||||
item->Animation.TargetState = LS_IDLE;
|
||||
|
|
|
@ -397,9 +397,9 @@ void lara_as_tightrope_fall(ItemInfo* item, CollisionInfo* coll)
|
|||
{
|
||||
// HACK: Set position command can't move Lara laterally?
|
||||
if (item->Animation.AnimNumber == LA_TIGHTROPE_FALL_LEFT)
|
||||
TranslateItem(item, coll->Setup.ForwardAngle - ANGLE(90.0f), CLICK(1), 0, 0);
|
||||
TranslateItem(item, coll->Setup.ForwardAngle - ANGLE(90.0f), CLICK(1));
|
||||
else if (item->Animation.AnimNumber == LA_TIGHTROPE_FALL_RIGHT)
|
||||
TranslateItem(item, coll->Setup.ForwardAngle + ANGLE(90.0f), CLICK(1), 0, 0);
|
||||
TranslateItem(item, coll->Setup.ForwardAngle + ANGLE(90.0f), CLICK(1));
|
||||
|
||||
item->Animation.VerticalVelocity = 10;
|
||||
}
|
||||
|
@ -895,7 +895,7 @@ void lara_as_pole_down(ItemInfo* item, CollisionInfo* coll)
|
|||
}
|
||||
|
||||
// TODO: In WAD.
|
||||
SoundEffect(SFX_TR4_LARA_POLE_LOOP, &item->Pose);
|
||||
SoundEffect(SFX_TR4_LARA_POLE_SLIDE_LOOP, &item->Pose);
|
||||
|
||||
if (TrInput & IN_ACTION)
|
||||
{
|
||||
|
|
|
@ -158,11 +158,11 @@ void AnimateShotgun(ItemInfo* laraItem, LaraWeaponType weaponType)
|
|||
//HKFlag = 1;
|
||||
|
||||
if (lara->Weapons[(int)LaraWeaponType::HK].HasSilencer)
|
||||
SoundEffect(SFX_TR4_LARA_HK_SILENCED, nullptr);
|
||||
SoundEffect(SFX_TR4_HK_SILENCED, nullptr);
|
||||
else
|
||||
{
|
||||
SoundEffect(SFX_TR4_EXPLOSION1, &laraItem->Pose, SoundEnvironment::Land, 1.0f, 0.4f);
|
||||
SoundEffect(SFX_TR4_LARA_HK_FIRE, &laraItem->Pose);
|
||||
SoundEffect(SFX_TR4_HK_FIRE, &laraItem->Pose);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -174,15 +174,12 @@ void AnimateShotgun(ItemInfo* laraItem, LaraWeaponType weaponType)
|
|||
item->Animation.TargetState = WEAPON_STATE_AIM;
|
||||
}
|
||||
|
||||
if (weaponType == LaraWeaponType::HarpoonGun && reloadHarpoonGun)
|
||||
item->Animation.TargetState = WEAPON_STATE_UNAIM;
|
||||
|
||||
if (item->Animation.TargetState != WEAPON_STATE_RECOIL &&
|
||||
//HKFlag &&
|
||||
!(lara->Weapons[(int)LaraWeaponType::HK].HasSilencer))
|
||||
{
|
||||
StopSoundEffect(SFX_TR4_LARA_HK_FIRE);
|
||||
SoundEffect(SFX_TR4_LARA_HK_STOP, &laraItem->Pose);
|
||||
StopSoundEffect(SFX_TR4_HK_FIRE);
|
||||
SoundEffect(SFX_TR4_HK_STOP, &laraItem->Pose);
|
||||
//HKFlag = 0;
|
||||
}
|
||||
}
|
||||
|
@ -234,11 +231,11 @@ void AnimateShotgun(ItemInfo* laraItem, LaraWeaponType weaponType)
|
|||
item->Animation.TargetState = WEAPON_STATE_UNDERWATER_RECOIL;
|
||||
|
||||
if (lara->Weapons[(int)LaraWeaponType::HK].HasSilencer)
|
||||
SoundEffect(SFX_TR4_LARA_HK_SILENCED, nullptr);
|
||||
SoundEffect(SFX_TR4_HK_SILENCED, nullptr);
|
||||
else
|
||||
{
|
||||
SoundEffect(SFX_TR4_EXPLOSION1, &laraItem->Pose, SoundEnvironment::Land, 1.0f, 0.4f);
|
||||
SoundEffect(SFX_TR4_LARA_HK_FIRE, &laraItem->Pose);
|
||||
SoundEffect(SFX_TR4_HK_FIRE, &laraItem->Pose);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -253,8 +250,8 @@ void AnimateShotgun(ItemInfo* laraItem, LaraWeaponType weaponType)
|
|||
//HKFlag &&
|
||||
!(lara->Weapons[(int)LaraWeaponType::HK].HasSilencer))
|
||||
{
|
||||
StopSoundEffect(SFX_TR4_LARA_HK_FIRE);
|
||||
SoundEffect(SFX_TR4_LARA_HK_STOP, &laraItem->Pose);
|
||||
StopSoundEffect(SFX_TR4_HK_FIRE);
|
||||
SoundEffect(SFX_TR4_HK_STOP, &laraItem->Pose);
|
||||
//HKFlag = 0;
|
||||
}
|
||||
/*else if (HKFlag)
|
||||
|
@ -352,7 +349,7 @@ void FireShotgun(ItemInfo* laraItem)
|
|||
|
||||
lara->RightArm.FlashGun = Weapons[(int)LaraWeaponType::Shotgun].FlashTime;
|
||||
|
||||
SoundEffect(SFX_TR4_EXPLOSION1, &laraItem->Pose, (SoundEnvironment)TestEnvironment(ENV_FLAG_WATER, laraItem));
|
||||
SoundEffect(SFX_TR4_EXPLOSION1, &laraItem->Pose, TestEnvironment(ENV_FLAG_WATER, laraItem) ? SoundEnvironment::Water : SoundEnvironment::Land);
|
||||
SoundEffect(Weapons[(int)LaraWeaponType::Shotgun].SampleNum, &laraItem->Pose);
|
||||
|
||||
Statistics.Game.AmmoUsed++;
|
||||
|
@ -558,7 +555,6 @@ void HarpoonBoltControl(short itemNumber)
|
|||
aboveWater = false;
|
||||
}
|
||||
|
||||
// Update bolt's position
|
||||
TranslateItem(item, item->Pose.Orientation, item->Animation.Velocity);
|
||||
}
|
||||
else
|
||||
|
@ -830,10 +826,6 @@ void GrenadeControl(short itemNumber)
|
|||
// Store old position for later
|
||||
auto oldPos = item->Pose.Position;
|
||||
|
||||
int xv;
|
||||
int yv;
|
||||
int zv;
|
||||
|
||||
item->Shade = 0xC210;
|
||||
|
||||
// Check if above water and update velocity and vertical velocity
|
||||
|
@ -890,7 +882,12 @@ void GrenadeControl(short itemNumber)
|
|||
}
|
||||
|
||||
// Update grenade position
|
||||
TranslateItem(item, item->Animation.TargetState/*???*/, item->Animation.Velocity, item->Animation.VerticalVelocity);
|
||||
auto velocity = Vector3Int(
|
||||
item->Animation.Velocity * phd_sin(item->Animation.TargetState),
|
||||
item->Animation.VerticalVelocity,
|
||||
item->Animation.Velocity * phd_cos(item->Animation.TargetState)
|
||||
);
|
||||
item->Pose.Position += velocity;
|
||||
|
||||
// Grenades that originate from first grenade when special ammo is selected
|
||||
if (item->ItemFlags[0] == (int)GrenadeType::Ultra)
|
||||
|
@ -908,10 +905,7 @@ void GrenadeControl(short itemNumber)
|
|||
short sYrot = item->Pose.Orientation.y;
|
||||
item->Pose.Orientation.y = item->Animation.TargetState; // ???
|
||||
|
||||
int xv = item->Animation.Velocity * phd_sin(item->Animation.TargetState);
|
||||
int yv = item->Animation.VerticalVelocity;
|
||||
int zv = item->Animation.Velocity * phd_cos(item->Animation.TargetState);
|
||||
DoProjectileDynamics(itemNumber, oldPos.x, oldPos.y, oldPos.z, xv, yv, zv);
|
||||
DoProjectileDynamics(itemNumber, oldPos.x, oldPos.y, oldPos.z, velocity.x, velocity.y, velocity.z);
|
||||
|
||||
item->Animation.TargetState = item->Pose.Orientation.y;
|
||||
item->Pose.Orientation.y = sYrot;
|
||||
|
@ -1131,7 +1125,7 @@ void FireRocket(ItemInfo* laraItem)
|
|||
{
|
||||
auto* lara = GetLaraInfo(laraItem);
|
||||
|
||||
Ammo& ammos = GetAmmo(laraItem, LaraWeaponType::RocketLauncher);
|
||||
auto& ammos = GetAmmo(laraItem, LaraWeaponType::RocketLauncher);
|
||||
if (!ammos)
|
||||
return;
|
||||
|
||||
|
@ -1327,8 +1321,8 @@ void RocketControl(short itemNumber)
|
|||
{
|
||||
// Smash objects are legacy objects from TRC, let's make them explode in the legacy way
|
||||
TriggerExplosionSparks(currentItem->Pose.Position.x, currentItem->Pose.Position.y, currentItem->Pose.Position.z, 3, -2, 0, currentItem->RoomNumber);
|
||||
auto pos = PHD_3DPOS(currentItem->Pose.Position.x, currentItem->Pose.Position.y - 128, currentItem->Pose.Position.z);
|
||||
TriggerShockwave(&pos, 48, 304, 96, 0, 96, 128, 24, 0, 0);
|
||||
auto pose = PHD_3DPOS(currentItem->Pose.Position.x, currentItem->Pose.Position.y - 128, currentItem->Pose.Position.z);
|
||||
TriggerShockwave(&pose, 48, 304, 96, 0, 96, 128, 24, 0, 0);
|
||||
ExplodeItemNode(currentItem, 0, 0, 128);
|
||||
short currentItemNumber = (currentItem - CollidedItems[0]);
|
||||
SmashObject(currentItemNumber);
|
||||
|
@ -1364,8 +1358,8 @@ void RocketControl(short itemNumber)
|
|||
if (currentMesh->HitPoints <= 0)
|
||||
{
|
||||
TriggerExplosionSparks(currentMesh->pos.Position.x, currentMesh->pos.Position.y, currentMesh->pos.Position.z, 3, -2, 0, item->RoomNumber);
|
||||
auto pos = PHD_3DPOS(currentMesh->pos.Position.x, currentMesh->pos.Position.y - 128, currentMesh->pos.Position.z, 0, currentMesh->pos.Orientation.y, 0);
|
||||
TriggerShockwave(&pos, 40, 176, 64, 0, 96, 128, 16, 0, 0);
|
||||
auto pose = PHD_3DPOS(currentMesh->pos.Position.x, currentMesh->pos.Position.y - 128, currentMesh->pos.Position.z, 0, currentMesh->pos.Orientation.y, 0);
|
||||
TriggerShockwave(&pose, 40, 176, 64, 0, 96, 128, 16, 0, 0);
|
||||
ShatterObject(nullptr, currentMesh, -128, item->RoomNumber, 0);
|
||||
SmashedMeshRoom[SmashedMeshCount] = item->RoomNumber;
|
||||
SmashedMesh[SmashedMeshCount] = currentMesh;
|
||||
|
@ -1412,7 +1406,7 @@ void FireCrossbow(ItemInfo* laraItem, PHD_3DPOS* pos)
|
|||
{
|
||||
auto* lara = GetLaraInfo(laraItem);
|
||||
|
||||
Ammo& ammos = GetAmmo(laraItem, LaraWeaponType::Crossbow);
|
||||
auto& ammos = GetAmmo(laraItem, LaraWeaponType::Crossbow);
|
||||
if (!ammos)
|
||||
return;
|
||||
|
||||
|
@ -1472,7 +1466,7 @@ void FireCrossbow(ItemInfo* laraItem, PHD_3DPOS* pos)
|
|||
|
||||
item->ItemFlags[0] = (int)lara->Weapons[(int)LaraWeaponType::Crossbow].SelectedAmmo;
|
||||
|
||||
SoundEffect(SFX_TR4_LARA_CROSSBOW, &laraItem->Pose);
|
||||
SoundEffect(SFX_TR4_CROSSBOW_FIRE, &laraItem->Pose);
|
||||
|
||||
Statistics.Level.AmmoUsed++;
|
||||
Statistics.Game.AmmoUsed++;
|
||||
|
@ -1506,7 +1500,7 @@ void CrossbowBoltControl(short itemNumber)
|
|||
// Update speed and check if above water
|
||||
if (TestEnvironment(ENV_FLAG_WATER, item))
|
||||
{
|
||||
Vector3Int bubblePos = { item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z };
|
||||
auto bubblePos = item->Pose.Position;
|
||||
|
||||
if (item->Animation.Velocity > 64)
|
||||
item->Animation.Velocity -= (item->Animation.Velocity >> 4);
|
||||
|
@ -1519,7 +1513,6 @@ void CrossbowBoltControl(short itemNumber)
|
|||
else
|
||||
aboveWater = true;
|
||||
|
||||
// Update bolt's position
|
||||
TranslateItem(item, item->Pose.Orientation, item->Animation.Velocity);
|
||||
|
||||
auto probe = GetCollision(item);
|
||||
|
@ -1790,7 +1783,7 @@ void RifleHandler(ItemInfo* laraItem, LaraWeaponType weaponType)
|
|||
{
|
||||
if (weaponType == LaraWeaponType::Shotgun || weaponType == LaraWeaponType::HK)
|
||||
{
|
||||
Vector3Int pos = {};
|
||||
auto pos = Vector3Int();
|
||||
pos.y = -64;
|
||||
GetLaraJointPosition(&pos, LM_RHAND);
|
||||
TriggerDynamicLight(
|
||||
|
@ -1894,7 +1887,7 @@ void SomeSparkEffect(int x, int y, int z, int count)
|
|||
{
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
auto * spark = &Sparks[GetFreeSpark()];
|
||||
auto* spark = GetFreeParticle();
|
||||
|
||||
spark->on = 1;
|
||||
spark->sR = 112;
|
||||
|
@ -1907,7 +1900,7 @@ void SomeSparkEffect(int x, int y, int z, int count)
|
|||
spark->dG = spark->sG >> 1;
|
||||
spark->dB = spark->sB >> 1;
|
||||
spark->sLife = 24;
|
||||
spark->transType = TransTypeEnum::COLADD;
|
||||
spark->blendMode = BLEND_MODES::BLENDMODE_ADDITIVE;
|
||||
spark->friction = 5;
|
||||
int random = GetRandomControl() & 0xFFF;
|
||||
spark->xVel = -128 * phd_sin(random << 4);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#pragma once
|
||||
#include "Game/control/control.h"
|
||||
#include "Specific/trmath.h"
|
||||
|
||||
enum class LaraWeaponType;
|
||||
|
@ -9,10 +10,10 @@ struct ItemInfo;
|
|||
constexpr auto HARPOON_DRAW_ANIM = 1;
|
||||
constexpr auto ROCKET_DRAW_ANIM = 0;
|
||||
constexpr auto HARPOON_VELOCITY = CLICK(1);
|
||||
constexpr auto HARPOON_TIME = 300;
|
||||
constexpr auto GRENADE_TIME = 120;
|
||||
constexpr auto ROCKET_TIME = 140;
|
||||
constexpr auto EXPLOSION_TRIGGER_TIME = 118;
|
||||
constexpr auto HARPOON_TIME = 10 * FPS;
|
||||
constexpr auto GRENADE_TIME = 4 * FPS;
|
||||
constexpr auto ROCKET_TIME = 4.5f * FPS;
|
||||
constexpr auto EXPLOSION_TRIGGER_TIME = 4 * FPS - 2;
|
||||
constexpr auto ROCKET_VELOCITY = CLICK(2);
|
||||
constexpr auto GRENADE_VELOCITY = CLICK(0.5f);
|
||||
constexpr auto MAX_GRENADE_VERTICAL_VELOCITY = CLICK(0.5f);
|
||||
|
|
|
@ -928,7 +928,7 @@ enum class HandStatus
|
|||
Special
|
||||
};
|
||||
|
||||
enum class TorchState : int
|
||||
enum class TorchState
|
||||
{
|
||||
Holding,
|
||||
Throwing,
|
||||
|
@ -1079,7 +1079,7 @@ struct ArmInfo
|
|||
Vector3Shrt Orientation;
|
||||
|
||||
bool Locked;
|
||||
short FlashGun;
|
||||
int FlashGun;
|
||||
};
|
||||
|
||||
struct FlareData
|
||||
|
@ -1236,6 +1236,12 @@ struct LaraControlData
|
|||
WaterStatus WaterStatus;
|
||||
LaraCountData Count;
|
||||
|
||||
WeaponControlData Weapon;
|
||||
RopeControlData Rope;
|
||||
TightropeControlData Tightrope;
|
||||
SubsuitControlData Subsuit;
|
||||
MinecartControlData Minecart;
|
||||
|
||||
bool CanLook;
|
||||
bool IsMoving;
|
||||
bool KeepLow;
|
||||
|
@ -1245,12 +1251,6 @@ struct LaraControlData
|
|||
bool CanMonkeySwing;
|
||||
bool RunJumpQueued;
|
||||
bool Locked;
|
||||
|
||||
WeaponControlData Weapon;
|
||||
RopeControlData Rope;
|
||||
TightropeControlData Tightrope;
|
||||
SubsuitControlData Subsuit;
|
||||
MinecartControlData Minecart;
|
||||
};
|
||||
|
||||
struct LaraInfo
|
||||
|
|
|
@ -123,7 +123,7 @@ bool TestLaraHang(ItemInfo* item, CollisionInfo* coll)
|
|||
if (LaraCeilingFront(item, lara->Control.MoveAngle, coll->Setup.Radius * 1.5f, 0) > -950)
|
||||
stopped = true;
|
||||
|
||||
// Backup item pos to restore it after coll tests
|
||||
// Restore backup pos after coll tests
|
||||
item->Pose = oldPose;
|
||||
|
||||
// Setup coll lara
|
||||
|
@ -337,12 +337,20 @@ bool TestLaraClimbIdle(ItemInfo* item, CollisionInfo* coll)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool TestLaraNearClimbableWall(ItemInfo* item, FloorInfo* floor)
|
||||
{
|
||||
if (floor == nullptr)
|
||||
floor = GetCollision(item).BottomBlock;
|
||||
|
||||
return ((1 << (GetQuadrant(item->Pose.Orientation.y) + 8)) & GetClimbFlags(floor));
|
||||
}
|
||||
|
||||
bool TestLaraHangOnClimbableWall(ItemInfo* item, CollisionInfo* coll)
|
||||
{
|
||||
auto* lara = GetLaraInfo(item);
|
||||
int shift, result;
|
||||
|
||||
if (!lara->Control.CanClimbLadder)
|
||||
if (!TestLaraNearClimbableWall(item))
|
||||
return false;
|
||||
|
||||
if (item->Animation.VerticalVelocity < 0)
|
||||
|
@ -1174,7 +1182,7 @@ bool TestLaraMonkeyStep(ItemInfo* item, CollisionInfo* coll)
|
|||
return false;
|
||||
}
|
||||
|
||||
// TODO: This function and its clone TestLaraCrawlMoveTolerance() should become obsolete with more accurate and accessible collision detection in the future.
|
||||
// TODO: This function should become obsolete with more accurate and accessible collision detection in the future.
|
||||
// For now, it supersedes old probes and is used alongside COLL_INFO. @Sezz 2021.10.24
|
||||
bool TestLaraMoveTolerance(ItemInfo* item, CollisionInfo* coll, MoveTestSetup testSetup, bool useCrawlSetup)
|
||||
{
|
||||
|
|
|
@ -19,6 +19,7 @@ bool DoLaraLedgeHang(ItemInfo* item, CollisionInfo* coll);
|
|||
|
||||
bool TestLaraClimbIdle(ItemInfo* item, CollisionInfo* coll);
|
||||
bool TestLaraHangOnClimbableWall(ItemInfo* item, CollisionInfo* coll);
|
||||
bool TestLaraNearClimbableWall(ItemInfo* item, FloorInfo* floor = nullptr);
|
||||
|
||||
bool TestLaraValidHangPosition(ItemInfo* item, CollisionInfo* coll);
|
||||
CornerType TestLaraHangCorner(ItemInfo* item, CollisionInfo* coll, float testAngle);
|
||||
|
|
|
@ -124,7 +124,7 @@ void AnimatePistols(ItemInfo* laraItem, LaraWeaponType weaponType)
|
|||
|
||||
lara->RightArm.FlashGun = weapon->FlashTime;
|
||||
|
||||
SoundEffect(SFX_TR4_EXPLOSION1, &laraItem->Pose, SoundEnvironment::Land, 0.9f, 0.5f);
|
||||
SoundEffect(SFX_TR4_EXPLOSION1, &laraItem->Pose, SoundEnvironment::Land, 0.9f, 0.3f);
|
||||
SoundEffect(weapon->SampleNum, &laraItem->Pose);
|
||||
soundPlayed = true;
|
||||
|
||||
|
@ -217,7 +217,7 @@ void AnimatePistols(ItemInfo* laraItem, LaraWeaponType weaponType)
|
|||
|
||||
if (!soundPlayed)
|
||||
{
|
||||
SoundEffect(SFX_TR4_EXPLOSION1, &laraItem->Pose, SoundEnvironment::Land, 0.9f, 0.5f);
|
||||
SoundEffect(SFX_TR4_EXPLOSION1, &laraItem->Pose, SoundEnvironment::Land, 0.9f, 0.3f);
|
||||
SoundEffect(weapon->SampleNum, &laraItem->Pose);
|
||||
}
|
||||
|
||||
|
|
|
@ -87,8 +87,6 @@ void AnimateLara(ItemInfo* item)
|
|||
if (anim->numberCommands > 0)
|
||||
{
|
||||
short* cmd = &g_Level.Commands[anim->commandIndex];
|
||||
int flags;
|
||||
int effectID = 0;
|
||||
|
||||
for (int i = anim->numberCommands; i > 0; i--)
|
||||
{
|
||||
|
@ -110,14 +108,20 @@ void AnimateLara(ItemInfo* item)
|
|||
}
|
||||
else
|
||||
{
|
||||
flags = cmd[1] & 0xC000;
|
||||
auto condition = flags ? (flags == (1 << 14) ? SoundEnvironment::Land : SoundEnvironment::Water) : SoundEnvironment::Always;
|
||||
bool inWater = (cmd[1] & 0x8000) != 0;
|
||||
bool inDry = (cmd[1] & 0x4000) != 0;
|
||||
bool always = (inWater && inDry) || (!inWater && !inDry);
|
||||
|
||||
SoundEnvironment condition = SoundEnvironment::Always;
|
||||
if (inWater) condition = SoundEnvironment::Water;
|
||||
if (inDry) condition = SoundEnvironment::Land;
|
||||
if (always) condition = SoundEnvironment::Always;
|
||||
|
||||
if (condition == SoundEnvironment::Always ||
|
||||
(condition == SoundEnvironment::Land && (lara->WaterSurfaceDist >= 0 || lara->WaterSurfaceDist == NO_HEIGHT)) ||
|
||||
(condition == SoundEnvironment::Water && lara->WaterSurfaceDist < -CLICK(0.5f) && lara->WaterSurfaceDist != NO_HEIGHT && !TestEnvironment(ENV_FLAG_SWAMP, item)))
|
||||
(condition == SoundEnvironment::Land && (lara->WaterSurfaceDist >= -SHALLOW_WATER_START_LEVEL || lara->WaterSurfaceDist == NO_HEIGHT)) ||
|
||||
(condition == SoundEnvironment::Water && lara->WaterSurfaceDist < -SHALLOW_WATER_START_LEVEL && lara->WaterSurfaceDist != NO_HEIGHT && !TestEnvironment(ENV_FLAG_SWAMP, item)))
|
||||
{
|
||||
SoundEffect(cmd[1] & 0x3FFF, &item->Pose, SoundEnvironment::Always);
|
||||
SoundEffect(cmd[1] & 0x3FFF, &item->Pose, condition);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -131,8 +135,7 @@ void AnimateLara(ItemInfo* item)
|
|||
break;
|
||||
}
|
||||
|
||||
effectID = cmd[1] & 0x3FFF;
|
||||
DoFlipEffect(effectID, item);
|
||||
DoFlipEffect((cmd[1] & 0x3FFF), item);
|
||||
|
||||
cmd += 2;
|
||||
break;
|
||||
|
@ -210,7 +213,7 @@ void AnimateLara(ItemInfo* item)
|
|||
|
||||
void AnimateItem(ItemInfo* item)
|
||||
{
|
||||
item->TouchBits = 0;
|
||||
item->TouchBits = NO_JOINT_BITS;
|
||||
item->HitStatus = false;
|
||||
|
||||
item->Animation.FrameNumber++;
|
||||
|
@ -280,8 +283,6 @@ void AnimateItem(ItemInfo* item)
|
|||
if (anim->numberCommands > 0)
|
||||
{
|
||||
short* cmd = &g_Level.Commands[anim->commandIndex];
|
||||
int flags;
|
||||
int effectID = 0;
|
||||
|
||||
for (int i = anim->numberCommands; i > 0; i--)
|
||||
{
|
||||
|
@ -302,10 +303,12 @@ void AnimateItem(ItemInfo* item)
|
|||
break;
|
||||
}
|
||||
|
||||
flags = cmd[1] & 0xC000;
|
||||
|
||||
if (!Objects[item->ObjectNumber].waterCreature)
|
||||
{
|
||||
bool inWater = (cmd[1] & 0x8000) != 0;
|
||||
bool inDry = (cmd[1] & 0x4000) != 0;
|
||||
bool always = (inWater && inDry) || (!inWater && !inDry);
|
||||
|
||||
if (item->RoomNumber == NO_ROOM)
|
||||
{
|
||||
item->Pose.Position.x = LaraItem->Pose.Position.x;
|
||||
|
@ -316,15 +319,15 @@ void AnimateItem(ItemInfo* item)
|
|||
}
|
||||
else if (TestEnvironment(ENV_FLAG_WATER, item))
|
||||
{
|
||||
if (!flags || flags == (int)SoundEnvironment::Water && (TestEnvironment(ENV_FLAG_WATER, Camera.pos.roomNumber) || Objects[item->ObjectNumber].intelligent))
|
||||
if (always || (inWater && TestEnvironment(ENV_FLAG_WATER, Camera.pos.roomNumber)))
|
||||
SoundEffect(cmd[1] & 0x3FFF, &item->Pose, SoundEnvironment::Always);
|
||||
}
|
||||
else if (!flags || flags == (int)SoundEnvironment::Land && !TestEnvironment(ENV_FLAG_WATER, Camera.pos.roomNumber))
|
||||
else if (always || (inDry && !TestEnvironment(ENV_FLAG_WATER, Camera.pos.roomNumber) && !TestEnvironment(ENV_FLAG_SWAMP, Camera.pos.roomNumber)))
|
||||
SoundEffect(cmd[1] & 0x3FFF, &item->Pose, SoundEnvironment::Always);
|
||||
}
|
||||
else
|
||||
{
|
||||
SoundEffect(cmd[1] & 0x3FFF, &item->Pose, (SoundEnvironment)TestEnvironment(ENV_FLAG_WATER, item));
|
||||
SoundEffect(cmd[1] & 0x3FFF, &item->Pose, TestEnvironment(ENV_FLAG_WATER, item) ? SoundEnvironment::Water : SoundEnvironment::Land);
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -336,8 +339,7 @@ void AnimateItem(ItemInfo* item)
|
|||
break;
|
||||
}
|
||||
|
||||
effectID = cmd[1] & 0x3FFF;
|
||||
DoFlipEffect(effectID, item);
|
||||
DoFlipEffect((cmd[1] & 0x3FFF), item);
|
||||
|
||||
cmd += 2;
|
||||
break;
|
||||
|
@ -418,9 +420,9 @@ bool TestLastFrame(ItemInfo* item, int animNumber)
|
|||
return (item->Animation.FrameNumber >= anim->frameEnd);
|
||||
}
|
||||
|
||||
void TranslateItem(ItemInfo* item, short orient, float forward, float vertical, float lateral)
|
||||
void TranslateItem(ItemInfo* item, short angle, float forward, float vertical, float lateral)
|
||||
{
|
||||
item->Pose.Position = TranslateVector(item->Pose.Position, orient, forward, vertical, lateral);
|
||||
item->Pose.Position = TranslateVector(item->Pose.Position, angle, forward, vertical, lateral);
|
||||
}
|
||||
|
||||
void TranslateItem(ItemInfo* item, Vector3Shrt orient, float distance)
|
||||
|
@ -542,7 +544,8 @@ int GetCurrentRelativeFrameNumber(ItemInfo* item)
|
|||
|
||||
int GetFrameNumber(ItemInfo* item, int frameToStart)
|
||||
{
|
||||
return GetFrameNumber(item->ObjectNumber, item->Animation.AnimNumber, frameToStart);
|
||||
int animNumber = item->Animation.AnimNumber - Objects[item->ObjectNumber].animIndex;
|
||||
return GetFrameNumber(item->ObjectNumber, animNumber, frameToStart);
|
||||
}
|
||||
|
||||
int GetFrameNumber(int objectID, int animNumber, int frameToStart)
|
||||
|
|
|
@ -74,7 +74,7 @@ void AnimateItem(ItemInfo* item);
|
|||
bool HasStateDispatch(ItemInfo* item, int targetState = -1);
|
||||
bool TestLastFrame(ItemInfo* item, int animNumber = -1);
|
||||
|
||||
void TranslateItem(ItemInfo* item, short orient, float forward, float vertical = 0.0f, float lateral = 0.0f);
|
||||
void TranslateItem(ItemInfo* item, short angle, float forward, float vertical = 0.0f, float lateral = 0.0f);
|
||||
void TranslateItem(ItemInfo* item, Vector3Shrt orient, float distance);
|
||||
void SetAnimation(ItemInfo* item, int animIndex, int frameToStart = 0);
|
||||
|
||||
|
|
|
@ -91,7 +91,7 @@ void LookAt(CAMERA_INFO* cam, short roll)
|
|||
Vector3 target = Vector3(cam->target.x, cam->target.y, cam->target.z);
|
||||
Vector3 up = Vector3(0.0f, -1.0f, 0.0f);
|
||||
float fov = TO_RAD(CurrentFOV / 1.333333f);
|
||||
float r = 0; TO_RAD(roll);
|
||||
float r = TO_RAD(roll);
|
||||
|
||||
g_Renderer.UpdateCameraMatrices(cam, r, fov);
|
||||
}
|
||||
|
@ -1077,7 +1077,7 @@ void BinocularCamera(ItemInfo* item)
|
|||
// TODO: Some of these inputs should ideally be blocked. @Sezz 2022.05.19
|
||||
if (InputBusy & (IN_DESELECT | IN_LOOK | IN_DRAW | IN_FLARE | IN_WALK | IN_JUMP))
|
||||
{
|
||||
item->MeshBits = -1;
|
||||
item->MeshBits = ALL_JOINT_BITS;
|
||||
lara->Inventory.IsBusy = false;
|
||||
lara->ExtraHeadRot = Vector3Shrt();
|
||||
lara->ExtraTorsoRot = Vector3Shrt();
|
||||
|
@ -1089,7 +1089,7 @@ void BinocularCamera(ItemInfo* item)
|
|||
}
|
||||
}
|
||||
|
||||
item->MeshBits = 0;
|
||||
item->MeshBits = NO_JOINT_BITS;
|
||||
AlterFOV(7 * (ANGLE(11.5f) - BinocularRange));
|
||||
|
||||
short headXRot = lara->ExtraHeadRot.x * 2;
|
||||
|
@ -1250,11 +1250,11 @@ void BinocularCamera(ItemInfo* item)
|
|||
firing = true;
|
||||
|
||||
if (lara->Weapons[(int)LaraWeaponType::HK].HasSilencer)
|
||||
SoundEffect(SFX_TR4_LARA_HK_SILENCED, nullptr);
|
||||
SoundEffect(SFX_TR4_HK_SILENCED, nullptr);
|
||||
else
|
||||
{
|
||||
SoundEffect(SFX_TR4_EXPLOSION1, nullptr, SoundEnvironment::Land, 1.0f, 0.4f);
|
||||
//SoundEffect(SFX_TR4_LARA_HK_FIRE, nullptr);
|
||||
//SoundEffect(SFX_TR4_HK_FIRE, nullptr);
|
||||
}
|
||||
}
|
||||
else if (lara->Weapons[(int)LaraWeaponType::HK].SelectedAmmo == WeaponAmmoType::Ammo2)
|
||||
|
@ -1271,11 +1271,11 @@ void BinocularCamera(ItemInfo* item)
|
|||
firing = true;
|
||||
|
||||
if (lara->Weapons[(int)LaraWeaponType::HK].HasSilencer)
|
||||
SoundEffect(SFX_TR4_LARA_HK_SILENCED, nullptr);
|
||||
SoundEffect(SFX_TR4_HK_SILENCED, nullptr);
|
||||
else
|
||||
{
|
||||
SoundEffect(SFX_TR4_EXPLOSION1, nullptr, SoundEnvironment::Land, 1.0f, 0.4f);
|
||||
SoundEffect(SFX_TR4_LARA_HK_FIRE, nullptr);
|
||||
SoundEffect(SFX_TR4_HK_FIRE, nullptr);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1283,11 +1283,11 @@ void BinocularCamera(ItemInfo* item)
|
|||
Camera.bounce = -16 - (GetRandomControl() & 0x1F);
|
||||
|
||||
if (lara->Weapons[(int)LaraWeaponType::HK].HasSilencer)
|
||||
SoundEffect(SFX_TR4_LARA_HK_SILENCED, nullptr);
|
||||
SoundEffect(SFX_TR4_HK_SILENCED, nullptr);
|
||||
else
|
||||
{
|
||||
SoundEffect(SFX_TR4_EXPLOSION1, nullptr, SoundEnvironment::Land, 1.0f, 0.4f);
|
||||
SoundEffect(SFX_TR4_LARA_HK_FIRE, nullptr);
|
||||
SoundEffect(SFX_TR4_HK_FIRE, nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1296,11 +1296,11 @@ void BinocularCamera(ItemInfo* item)
|
|||
if (LSHKTimer)
|
||||
{
|
||||
if (lara->Weapons[(int)LaraWeaponType::HK].HasSilencer)
|
||||
SoundEffect(SFX_TR4_LARA_HK_SILENCED, nullptr);
|
||||
SoundEffect(SFX_TR4_HK_SILENCED, nullptr);
|
||||
else
|
||||
{
|
||||
SoundEffect(SFX_TR4_EXPLOSION1, nullptr, SoundEnvironment::Land, 1.0f, 0.4f);
|
||||
SoundEffect(SFX_TR4_LARA_HK_FIRE, nullptr);
|
||||
SoundEffect(SFX_TR4_HK_FIRE, nullptr);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1309,11 +1309,11 @@ void BinocularCamera(ItemInfo* item)
|
|||
firing = true;
|
||||
|
||||
if (lara->Weapons[(int)LaraWeaponType::HK].HasSilencer)
|
||||
SoundEffect(SFX_TR4_LARA_HK_SILENCED, nullptr);
|
||||
SoundEffect(SFX_TR4_HK_SILENCED, nullptr);
|
||||
else
|
||||
{
|
||||
SoundEffect(SFX_TR4_EXPLOSION1, nullptr, SoundEnvironment::Land, 1.0f, 0.4f);
|
||||
SoundEffect(SFX_TR4_LARA_HK_FIRE, nullptr);
|
||||
SoundEffect(SFX_TR4_HK_FIRE, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -94,7 +94,7 @@ void GenericSphereBoxCollision(short itemNumber, ItemInfo* laraItem, CollisionIn
|
|||
}
|
||||
}
|
||||
|
||||
bool GetCollidedObjects(ItemInfo* collidingItem, int radius, bool onlyVisible, ItemInfo** collidedItems, MESH_INFO** collidedMeshes, int ignoreLara)
|
||||
bool GetCollidedObjects(ItemInfo* collidingItem, int radius, bool onlyVisible, ItemInfo** collidedItems, MESH_INFO** collidedMeshes, bool ignoreLara)
|
||||
{
|
||||
short numItems = 0;
|
||||
short numMeshes = 0;
|
||||
|
@ -157,7 +157,7 @@ bool GetCollidedObjects(ItemInfo* collidingItem, int radius, bool onlyVisible, I
|
|||
if (item == collidingItem ||
|
||||
item->ObjectNumber == ID_LARA && ignoreLara ||
|
||||
item->Flags & 0x8000 ||
|
||||
item->MeshBits == 0 ||
|
||||
item->MeshBits == NO_JOINT_BITS ||
|
||||
(Objects[item->ObjectNumber].drawRoutine == NULL && item->ObjectNumber != ID_LARA) ||
|
||||
(Objects[item->ObjectNumber].collision == NULL && item->ObjectNumber != ID_LARA) ||
|
||||
onlyVisible && item->Status == ITEM_INVISIBLE ||
|
||||
|
@ -1744,7 +1744,7 @@ void AIPickupCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll
|
|||
item->Status = ITEM_INVISIBLE;
|
||||
}
|
||||
|
||||
void ObjectCollision(short const itemNumber, ItemInfo* laraItem, CollisionInfo * coll)
|
||||
void ObjectCollision(short const itemNumber, ItemInfo* laraItem, CollisionInfo* coll)
|
||||
{
|
||||
auto* item = &g_Level.Items[itemNumber];
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ struct OBJECT_COLLISION_BOUNDS
|
|||
};
|
||||
|
||||
void GenericSphereBoxCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll);
|
||||
bool GetCollidedObjects(ItemInfo* collidingItem, int radius, bool onlyVisible, ItemInfo** collidedItems, MESH_INFO** collidedMeshes, int flag2);
|
||||
bool GetCollidedObjects(ItemInfo* collidingItem, int radius, bool onlyVisible, ItemInfo** collidedItems, MESH_INFO** collidedMeshes, bool ignoreLara);
|
||||
bool TestWithGlobalCollisionBounds(ItemInfo* item, ItemInfo* laraItem, CollisionInfo* coll);
|
||||
void TestForObjectOnLedge(ItemInfo* item, CollisionInfo* coll);
|
||||
|
||||
|
|
|
@ -95,39 +95,25 @@ bool TestItemRoomCollisionAABB(ItemInfo* item)
|
|||
|
||||
auto test = [item](short x, short y, short z, bool floor)
|
||||
{
|
||||
CollisionPosition pos = GetCollision(x, y, z, item->RoomNumber).Position;
|
||||
if (floor) return y > pos.Floor;
|
||||
return y < pos.Ceiling;
|
||||
auto collPos = GetCollision(x, y, z, item->RoomNumber).Position;
|
||||
if (floor) return y > collPos.Floor;
|
||||
return y < collPos.Ceiling;
|
||||
};
|
||||
|
||||
bool collided =
|
||||
test(box.X1, minY, box.Z1, true)
|
||||
|| test(box.X2, minY, box.Z1, true)
|
||||
|| test(box.X1, minY, box.Z2, true)
|
||||
|| test(box.X2, minY, box.Z2, true)
|
||||
|| test(box.X1, maxY, box.Z1, false)
|
||||
|| test(box.X2, maxY, box.Z1, false)
|
||||
|| test(box.X1, maxY, box.Z2, false)
|
||||
|| test(box.X2, maxY, box.Z2, false);
|
||||
test(box.X1, minY, box.Z1, true) ||
|
||||
test(box.X2, minY, box.Z1, true) ||
|
||||
test(box.X1, minY, box.Z2, true) ||
|
||||
test(box.X2, minY, box.Z2, true) ||
|
||||
test(box.X1, maxY, box.Z1, false) ||
|
||||
test(box.X2, maxY, box.Z1, false) ||
|
||||
test(box.X1, maxY, box.Z2, false) ||
|
||||
test(box.X2, maxY, box.Z2, false) ;
|
||||
|
||||
return collided;
|
||||
}
|
||||
|
||||
CollisionResult GetCollision(ItemInfo* item, short orient, int forward, int vertical, int lateral)
|
||||
{
|
||||
// NOTE: GetRoom() call is necessary to fetch the index of the room directly above in order to perform a correct L-shaped test.
|
||||
// Probes MUST traverse through portals between rooms, otherwise they will not work correctly.
|
||||
|
||||
auto point = TranslateVector(item->Pose.Position, orient, forward, vertical, lateral);
|
||||
return GetCollision(point.x, point.y, point.z, GetRoom(item->Location, item->Pose.Position.x, point.y, item->Pose.Position.z).roomNumber);
|
||||
}
|
||||
|
||||
CollisionResult GetCollision(Vector3 pos, int roomIndex, short orient, int forward, int vertical, int lateral)
|
||||
{
|
||||
auto point = TranslateVector(pos, orient, forward, vertical, lateral);
|
||||
return GetCollision(point.x, point.y, point.z, roomIndex);
|
||||
}
|
||||
|
||||
// Overload used to quickly get point/room collision parameters at a given item's position.
|
||||
CollisionResult GetCollision(ItemInfo* item)
|
||||
{
|
||||
auto room = item->RoomNumber;
|
||||
|
@ -138,6 +124,30 @@ CollisionResult GetCollision(ItemInfo* item)
|
|||
return result;
|
||||
}
|
||||
|
||||
// Overload used to probe point/room collision parameters from a given item's position.
|
||||
CollisionResult GetCollision(ItemInfo* item, short angle, float forward, float vertical, float lateral)
|
||||
{
|
||||
auto point = TranslateVector(item->Pose.Position, angle, forward, vertical, lateral);
|
||||
int adjacentRoomNumber = GetRoom(item->Location, item->Pose.Position.x, point.y, item->Pose.Position.z).roomNumber;
|
||||
return GetCollision(point.x, point.y, point.z, adjacentRoomNumber);
|
||||
}
|
||||
|
||||
// Overload used to probe point/room collision parameters from a given position.
|
||||
CollisionResult GetCollision(Vector3Int pos, int roomNumber, short angle, float forward, float vertical, float lateral)
|
||||
{
|
||||
short tempRoomNumber = roomNumber;
|
||||
auto location = ROOM_VECTOR{ GetFloor(pos.x, pos.y, pos.z, &tempRoomNumber)->Room, pos.y };
|
||||
|
||||
auto point = TranslateVector(pos, angle, forward, vertical, lateral);
|
||||
int adjacentRoomNumber = GetRoom(location, pos.x, point.y, pos.z).roomNumber;
|
||||
return GetCollision(point.x, point.y, point.z, adjacentRoomNumber);
|
||||
}
|
||||
|
||||
// Overload used as a universal wrapper across collisional code to replace
|
||||
// triads of roomNumber-GetFloor()-GetFloorHeight() operations.
|
||||
// The advantage is that it does NOT modify the incoming roomNumber argument,
|
||||
// instead storing one modified by GetFloor() within the returned CollisionResult struct.
|
||||
// This way, no external variables are modified as output arguments.
|
||||
CollisionResult GetCollision(int x, int y, int z, short roomNumber)
|
||||
{
|
||||
auto room = roomNumber;
|
||||
|
@ -148,14 +158,16 @@ CollisionResult GetCollision(int x, int y, int z, short roomNumber)
|
|||
return result;
|
||||
}
|
||||
|
||||
// A reworked legacy GetFloorHeight() function which writes data
|
||||
// into a special CollisionResult struct instead of global variables.
|
||||
// It writes for both floor and ceiling heights at the same coordinates, meaning it should be used
|
||||
// in place of successive GetFloorHeight() and GetCeilingHeight() calls to increase readability.
|
||||
CollisionResult GetCollision(FloorInfo* floor, int x, int y, int z)
|
||||
{
|
||||
CollisionResult result = {};
|
||||
|
||||
// Record coordinates.
|
||||
result.Coordinates.x = x;
|
||||
result.Coordinates.y = y;
|
||||
result.Coordinates.z = z;
|
||||
result.Coordinates = Vector3(x, y, z);
|
||||
|
||||
// Return provided block into result as itself.
|
||||
result.Block = floor;
|
||||
|
@ -701,7 +713,7 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, Vector3Int offset, bo
|
|||
if (coll->TriangleAtLeft() && !coll->MiddleLeft.FloorSlope)
|
||||
{
|
||||
// HACK: Force slight push-out to the left side to avoid stucking
|
||||
TranslateItem(item, coll->Setup.ForwardAngle + ANGLE(8.0f), item->Animation.Velocity, 0, 0);
|
||||
TranslateItem(item, coll->Setup.ForwardAngle + ANGLE(8.0f), item->Animation.Velocity);
|
||||
|
||||
coll->Shift.x = coll->Setup.OldPosition.x - xPos;
|
||||
coll->Shift.z = coll->Setup.OldPosition.z - zPos;
|
||||
|
@ -753,7 +765,7 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, Vector3Int offset, bo
|
|||
if (coll->TriangleAtRight() && !coll->MiddleRight.FloorSlope)
|
||||
{
|
||||
// HACK: Force slight push-out to the right side to avoid stucking
|
||||
TranslateItem(item, coll->Setup.ForwardAngle - ANGLE(8.0f), item->Animation.Velocity, 0, 0);
|
||||
TranslateItem(item, coll->Setup.ForwardAngle - ANGLE(8.0f), item->Animation.Velocity);
|
||||
|
||||
coll->Shift.x = coll->Setup.OldPosition.x - xPos;
|
||||
coll->Shift.z = coll->Setup.OldPosition.z - zPos;
|
||||
|
@ -1265,12 +1277,13 @@ int GetWaterDepth(int x, int y, int z, short roomNumber)
|
|||
while (floor->RoomAbove(x, y, z).value_or(NO_ROOM) != NO_ROOM)
|
||||
{
|
||||
room = &g_Level.Rooms[floor->RoomAbove(x, y, z).value_or(floor->Room)];
|
||||
|
||||
if (!TestEnvironment(ENV_FLAG_WATER, room) &&
|
||||
!TestEnvironment(ENV_FLAG_SWAMP, room))
|
||||
{
|
||||
int waterHeight = floor->CeilingHeight(x, z);
|
||||
floor = GetFloor(x, y, z, &roomNumber);
|
||||
return (GetFloorHeight(floor, x, y, z) - waterHeight);
|
||||
int floorHeight = GetCollision(floor, x, y, z).BottomBlock->FloorHeight(x, z);
|
||||
return (floorHeight - waterHeight);
|
||||
}
|
||||
|
||||
floor = GetSector(room, x - room->x, z - room->z);
|
||||
|
|
|
@ -88,9 +88,9 @@ struct CollisionSetup
|
|||
|
||||
// Preserve old parameters to restore later
|
||||
Vector3Int OldPosition;
|
||||
int OldState;
|
||||
int OldAnimNumber;
|
||||
int OldFrameNumber;
|
||||
int OldState;
|
||||
};
|
||||
|
||||
struct CollisionInfo
|
||||
|
@ -121,11 +121,12 @@ struct CollisionInfo
|
|||
};
|
||||
|
||||
[[nodiscard]] bool TestItemRoomCollisionAABB(ItemInfo* item);
|
||||
CollisionResult GetCollision(ItemInfo* item, short orient, int forward, int vertical = 0, int lateral = 0);
|
||||
CollisionResult GetCollision(Vector3 pos, int roomIndex, short orient, int forward, int vertical = 0, int lateral = 0);
|
||||
CollisionResult GetCollision(FloorInfo* floor, int x, int y, int z);
|
||||
CollisionResult GetCollision(int x, int y, int z, short roomNumber);
|
||||
|
||||
CollisionResult GetCollision(ItemInfo* item);
|
||||
CollisionResult GetCollision(ItemInfo* item, short angle, float forward, float vertical = 0, float lateral = 0);
|
||||
CollisionResult GetCollision(Vector3Int pos, int roomNumber, short angle, float forward, float vertical = 0, float lateral = 0);
|
||||
CollisionResult GetCollision(int x, int y, int z, short roomNumber);
|
||||
CollisionResult GetCollision(FloorInfo* floor, int x, int y, int z);
|
||||
|
||||
void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, Vector3Int offset, bool resetRoom = false);
|
||||
void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, bool resetRoom = false);
|
||||
|
|
|
@ -35,25 +35,25 @@ int GetSpheres(ItemInfo* item, SPHERE* ptr, int worldSpace, Matrix local)
|
|||
return num;
|
||||
}
|
||||
|
||||
int TestCollision(ItemInfo* item, ItemInfo* l)
|
||||
int TestCollision(ItemInfo* item, ItemInfo* laraItem)
|
||||
{
|
||||
int flags = 0;
|
||||
|
||||
int creatureSphereCount = GetSpheres(item, CreatureSpheres, SPHERES_SPACE_WORLD, Matrix::Identity);
|
||||
int laraSphereCount = GetSpheres(l, LaraSpheres, SPHERES_SPACE_WORLD, Matrix::Identity);
|
||||
int laraSphereCount = GetSpheres(laraItem, LaraSpheres, SPHERES_SPACE_WORLD, Matrix::Identity);
|
||||
|
||||
l->TouchBits = 0;
|
||||
laraItem->TouchBits = NO_JOINT_BITS;
|
||||
|
||||
if (creatureSphereCount <= 0)
|
||||
{
|
||||
item->TouchBits = 0;
|
||||
item->TouchBits = NO_JOINT_BITS;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < creatureSphereCount; i++)
|
||||
{
|
||||
SPHERE* ptr1 = &CreatureSpheres[i];
|
||||
auto* ptr1 = &CreatureSpheres[i];
|
||||
|
||||
int x1 = item->Pose.Position.x + ptr1->x;
|
||||
int y1 = item->Pose.Position.y + ptr1->y;
|
||||
|
@ -64,7 +64,7 @@ int TestCollision(ItemInfo* item, ItemInfo* l)
|
|||
{
|
||||
for (int j = 0; j < laraSphereCount; j++)
|
||||
{
|
||||
SPHERE* ptr2 = &LaraSpheres[j];
|
||||
auto* ptr2 = &LaraSpheres[j];
|
||||
|
||||
int x2 = item->Pose.Position.x + ptr2->x;
|
||||
int y2 = item->Pose.Position.y + ptr2->y;
|
||||
|
@ -78,10 +78,11 @@ int TestCollision(ItemInfo* item, ItemInfo* l)
|
|||
int dz = z1 - z2;
|
||||
int r = r1 + r2;
|
||||
|
||||
if (SQUARE(dx) + SQUARE(dy) + SQUARE(dz) < SQUARE(r))
|
||||
if ((pow(dx, 2) + pow(dy, 2) + pow(dz, 2)) < pow(r, 2))
|
||||
{
|
||||
l->TouchBits |= (1 << j);
|
||||
flags |= (1 << i);
|
||||
item->SetBits(JointBitType::Touch, i);
|
||||
laraItem->SetBits(JointBitType::Touch, j);
|
||||
flags |= 1 << i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -89,7 +90,6 @@ int TestCollision(ItemInfo* item, ItemInfo* l)
|
|||
}
|
||||
}
|
||||
|
||||
item->TouchBits = flags;
|
||||
return flags;
|
||||
}
|
||||
}
|
||||
|
@ -100,7 +100,7 @@ void GetJointAbsPosition(ItemInfo* item, Vector3Int* vec, int joint)
|
|||
short itemNumber = item - g_Level.Items.data();
|
||||
|
||||
// Use matrices done in the renderer and transform the input vector
|
||||
Vector3 p = Vector3(vec->x, vec->y, vec->z);
|
||||
auto p = vec->ToVector3();
|
||||
g_Renderer.GetItemAbsBonePosition(itemNumber, &p, joint);
|
||||
|
||||
// Store the result
|
||||
|
|
|
@ -747,9 +747,9 @@ void CreatureDie(short itemNumber, int explode)
|
|||
if (explode)
|
||||
{
|
||||
if (Objects[item->ObjectNumber].hitEffect)
|
||||
ExplodingDeath(itemNumber, ALL_MESHBITS, EXPLODE_HIT_EFFECT);
|
||||
ExplodingDeath(itemNumber, ALL_JOINT_BITS, EXPLODE_HIT_EFFECT);
|
||||
else
|
||||
ExplodingDeath(itemNumber, ALL_MESHBITS, EXPLODE_NORMAL);
|
||||
ExplodingDeath(itemNumber, ALL_JOINT_BITS, EXPLODE_NORMAL);
|
||||
|
||||
KillItem(itemNumber);
|
||||
}
|
||||
|
|
|
@ -241,7 +241,7 @@ GameStatus ControlPhase(int numFrames, int demoMode)
|
|||
Camera.bounce = 0;
|
||||
AlterFOV(ANGLE(80.0f));
|
||||
|
||||
LaraItem->MeshBits = 0xFFFFFFFF;
|
||||
LaraItem->MeshBits = ALL_JOINT_BITS;
|
||||
Lara.Inventory.IsBusy = false;
|
||||
ResetLaraFlex(LaraItem);
|
||||
|
||||
|
@ -411,7 +411,7 @@ GameStatus ControlPhase(int numFrames, int demoMode)
|
|||
RumbleScreen();
|
||||
|
||||
PlaySoundSources();
|
||||
DoFlipEffect(FlipEffect);
|
||||
DoFlipEffect(FlipEffect, LaraItem);
|
||||
|
||||
UpdateFadeScreenAndCinematicBars();
|
||||
|
||||
|
@ -490,7 +490,7 @@ GameStatus DoTitle(int index, std::string const& ambient)
|
|||
g_GameScript->InitCallbacks();
|
||||
g_GameStringsHandler->SetCallbackDrawString([](std::string const key, D3DCOLOR col, int x, int y, int flags)
|
||||
{
|
||||
g_Renderer.DrawString(float(x)/float(g_Configuration.Width) * ASSUMED_WIDTH_FOR_TEXT_DRAWING, float(y)/float(g_Configuration.Height) * ASSUMED_HEIGHT_FOR_TEXT_DRAWING, key.c_str(), col, flags);
|
||||
g_Renderer.DrawString(float(x)/float(g_Configuration.Width) * REFERENCE_RES_WIDTH, float(y)/float(g_Configuration.Height) * REFERENCE_RES_HEIGHT, key.c_str(), col, flags);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -576,16 +576,6 @@ GameStatus DoTitle(int index, std::string const& ambient)
|
|||
|
||||
GameStatus DoLevel(int index, std::string const& ambient, bool loadFromSavegame)
|
||||
{
|
||||
// If not loading a savegame, then clear all the infos
|
||||
if (!loadFromSavegame)
|
||||
{
|
||||
Statistics.Level.Timer = 0;
|
||||
Statistics.Level.Distance = 0;
|
||||
Statistics.Level.AmmoUsed = 0;
|
||||
Statistics.Level.AmmoHits = 0;
|
||||
Statistics.Level.Kills = 0;
|
||||
}
|
||||
|
||||
// Reset all the globals for the game which needs this
|
||||
CleanUp();
|
||||
|
||||
|
@ -609,7 +599,7 @@ GameStatus DoLevel(int index, std::string const& ambient, bool loadFromSavegame)
|
|||
g_GameScript->InitCallbacks();
|
||||
g_GameStringsHandler->SetCallbackDrawString([](std::string const key, D3DCOLOR col, int x, int y, int flags)
|
||||
{
|
||||
g_Renderer.DrawString(float(x)/float(g_Configuration.Width) * ASSUMED_WIDTH_FOR_TEXT_DRAWING, float(y)/float(g_Configuration.Height) * ASSUMED_HEIGHT_FOR_TEXT_DRAWING, key.c_str(), col, flags);
|
||||
g_Renderer.DrawString(float(x)/float(g_Configuration.Width) * REFERENCE_RES_WIDTH, float(y)/float(g_Configuration.Height) * REFERENCE_RES_HEIGHT, key.c_str(), col, flags);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -637,15 +627,17 @@ GameStatus DoLevel(int index, std::string const& ambient, bool loadFromSavegame)
|
|||
}
|
||||
else
|
||||
{
|
||||
// If not loading a savegame, then clear all the infos
|
||||
Statistics.Level = {};
|
||||
RequiredStartPos = false;
|
||||
|
||||
if (InitialiseGame)
|
||||
{
|
||||
// Clear all game infos as well
|
||||
Statistics.Game = {};
|
||||
GameTimer = 0;
|
||||
RequiredStartPos = false;
|
||||
InitialiseGame = false;
|
||||
}
|
||||
|
||||
Statistics.Level.Timer = 0;
|
||||
}
|
||||
|
||||
g_Gui.SetInventoryItemChosen(NO_ITEM);
|
||||
|
@ -677,8 +669,6 @@ GameStatus DoLevel(int index, std::string const& ambient, bool loadFromSavegame)
|
|||
while (DoTheGame)
|
||||
{
|
||||
result = ControlPhase(nFrames, 0);
|
||||
nFrames = DrawPhase();
|
||||
Sound_UpdateScene();
|
||||
|
||||
if (result == GameStatus::ExitToTitle ||
|
||||
result == GameStatus::LoadGame ||
|
||||
|
@ -694,6 +684,9 @@ GameStatus DoLevel(int index, std::string const& ambient, bool loadFromSavegame)
|
|||
|
||||
return result;
|
||||
}
|
||||
|
||||
nFrames = DrawPhase();
|
||||
Sound_UpdateScene();
|
||||
}
|
||||
|
||||
g_GameScript->ResetScripts(true);
|
||||
|
|
|
@ -45,6 +45,8 @@ constexpr int MAX_ROOMS = 1024;
|
|||
constexpr int WIBBLE_SPEED = 4;
|
||||
constexpr int WIBBLE_MAX = UCHAR_MAX - WIBBLE_SPEED + 1;
|
||||
|
||||
constexpr auto FPS = 30;
|
||||
|
||||
extern int GameTimer;
|
||||
extern int RumbleTimer;
|
||||
extern int GlobalCounter;
|
||||
|
|
|
@ -41,4 +41,4 @@ void MeshSwapToPour(ItemInfo* item);
|
|||
void MeshSwapFromPour(ItemInfo* item);
|
||||
void FlashOrange(ItemInfo* item);
|
||||
|
||||
void DoFlipEffect(int number, ItemInfo* item = NULL);
|
||||
void DoFlipEffect(int number, ItemInfo* item = nullptr);
|
||||
|
|
|
@ -94,7 +94,7 @@ bool GetTargetOnLOS(GameVector* src, GameVector* dest, bool drawTarget, bool fir
|
|||
Lara.Control.Weapon.Fired = true;
|
||||
|
||||
if (Lara.Control.Weapon.GunType == LaraWeaponType::Revolver)
|
||||
SoundEffect(SFX_TR4_DESSERT_EAGLE_FIRE, nullptr);
|
||||
SoundEffect(SFX_TR4_REVOLVER_FIRE, nullptr);
|
||||
}
|
||||
|
||||
bool hit = false;
|
||||
|
|
|
@ -125,7 +125,7 @@ int SwitchTrigger(short itemNumber, short timer)
|
|||
item->Timer = timer;
|
||||
item->Status = ITEM_ACTIVE;
|
||||
if (timer != 1)
|
||||
item->Timer = 30 * timer;
|
||||
item->Timer = FPS * timer;
|
||||
return 1;
|
||||
}
|
||||
if (item->TriggerFlags != 6 || item->Animation.ActiveState)
|
||||
|
@ -456,7 +456,7 @@ void TestTriggers(FloorInfo* floor, int x, int y, int z, bool heavy, int heavyFl
|
|||
|
||||
item->Timer = timer;
|
||||
if (timer != 1)
|
||||
item->Timer = 30 * timer;
|
||||
item->Timer = FPS * timer;
|
||||
|
||||
if (triggerType == TRIGGER_TYPES::SWITCH ||
|
||||
triggerType == TRIGGER_TYPES::HEAVYSWITCH)
|
||||
|
@ -523,7 +523,7 @@ void TestTriggers(FloorInfo* floor, int x, int y, int z, bool heavy, int heavyFl
|
|||
{
|
||||
if (item->Status == ITEM_INVISIBLE)
|
||||
{
|
||||
item->TouchBits = 0;
|
||||
item->TouchBits = NO_JOINT_BITS;
|
||||
if (EnableBaddyAI(value, 0))
|
||||
{
|
||||
item->Status = ITEM_ACTIVE;
|
||||
|
@ -538,7 +538,7 @@ void TestTriggers(FloorInfo* floor, int x, int y, int z, bool heavy, int heavyFl
|
|||
}
|
||||
else
|
||||
{
|
||||
item->TouchBits = 0;
|
||||
item->TouchBits = NO_JOINT_BITS;
|
||||
item->Status = ITEM_ACTIVE;
|
||||
AddActiveItem(value);
|
||||
EnableBaddyAI(value, 1);
|
||||
|
@ -546,7 +546,7 @@ void TestTriggers(FloorInfo* floor, int x, int y, int z, bool heavy, int heavyFl
|
|||
}
|
||||
else
|
||||
{
|
||||
item->TouchBits = 0;
|
||||
item->TouchBits = NO_JOINT_BITS;
|
||||
AddActiveItem(value);
|
||||
item->Status = ITEM_ACTIVE;
|
||||
}
|
||||
|
@ -576,7 +576,7 @@ void TestTriggers(FloorInfo* floor, int x, int y, int z, bool heavy, int heavyFl
|
|||
|
||||
if (Camera.number != Camera.last || triggerType == TRIGGER_TYPES::SWITCH)
|
||||
{
|
||||
Camera.timer = (trigger & 0xFF) * 30;
|
||||
Camera.timer = (trigger & 0xFF) * FPS;
|
||||
Camera.type = heavy ? CameraType::Heavy : CameraType::Fixed;
|
||||
if (trigger & ONESHOT)
|
||||
g_Level.Cameras[Camera.number].flags |= ONESHOT;
|
||||
|
@ -746,7 +746,7 @@ void ProcessSectorFlags(FloorInfo* floor)
|
|||
}
|
||||
|
||||
// Set climb status
|
||||
if ((1 << (GetQuadrant(LaraItem->Pose.Orientation.y) + 8)) & GetClimbFlags(floor))
|
||||
if (TestLaraNearClimbableWall(LaraItem, floor))
|
||||
Lara.Control.CanClimbLadder = true;
|
||||
else
|
||||
Lara.Control.CanClimbLadder = false;
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
#include "Game/Lara/lara.h"
|
||||
#include "Specific/level.h"
|
||||
#include "Specific/prng.h"
|
||||
#include "Specific/setup.h"
|
||||
#include "Renderer/Renderer11Enums.h"
|
||||
|
||||
#define MAX_TRIGGER_RANGE 0x4000
|
||||
using namespace TEN::Math::Random;
|
||||
|
@ -41,7 +43,7 @@ void TriggerChaffEffects(int flareAge)
|
|||
TriggerChaffEffects(LaraItem, &pos, &vel, LaraItem->Animation.Velocity, (bool)(g_Level.Rooms[LaraItem->RoomNumber].flags & ENV_FLAG_WATER), flareAge);
|
||||
}
|
||||
|
||||
void TriggerChaffEffects(ItemInfo* Item,int age)
|
||||
void TriggerChaffEffects(ItemInfo* Item, int age)
|
||||
{
|
||||
Matrix world
|
||||
= Matrix::CreateTranslation(-6, 6, 32)
|
||||
|
@ -62,10 +64,10 @@ void TriggerChaffEffects(ItemInfo* Item,int age)
|
|||
vel.y = world.Translation().y;
|
||||
vel.z = world.Translation().z;
|
||||
|
||||
TriggerChaffEffects(Item, &pos, &vel, Item->Animation.Velocity, (bool)(g_Level.Rooms[Item->RoomNumber].flags & ENV_FLAG_WATER),age);
|
||||
TriggerChaffEffects(Item, &pos, &vel, Item->Animation.Velocity, (bool)(g_Level.Rooms[Item->RoomNumber].flags & ENV_FLAG_WATER), age);
|
||||
}
|
||||
|
||||
void TriggerChaffEffects(ItemInfo* item, Vector3Int* pos, Vector3Int* vel, int speed, bool isUnderwater,int age)
|
||||
void TriggerChaffEffects(ItemInfo* item, Vector3Int* pos, Vector3Int* vel, int speed, bool isUnderwater, int age)
|
||||
{
|
||||
int numSparks = (int)GenerateFloat(2, 5);
|
||||
for (int i = 0; i < numSparks; i++)
|
||||
|
@ -83,7 +85,7 @@ void TriggerChaffEffects(ItemInfo* item, Vector3Int* pos, Vector3Int* vel, int s
|
|||
color.g = (GetRandomDraw() & 127) + 64;
|
||||
color.b = 192 - color.g;
|
||||
|
||||
TriggerChaffSparkles(pos, vel, &color,age,item);
|
||||
TriggerChaffSparkles(pos, vel, &color, age, item);
|
||||
if (isUnderwater)
|
||||
{
|
||||
TriggerChaffBubbles(pos, item->RoomNumber);
|
||||
|
@ -99,7 +101,7 @@ void TriggerChaffEffects(ItemInfo* item, Vector3Int* pos, Vector3Int* vel, int s
|
|||
}
|
||||
|
||||
|
||||
void TriggerChaffSparkles (Vector3Int* pos, Vector3Int* vel, CVECTOR* color,int age,ItemInfo* item)
|
||||
void TriggerChaffSparkles(Vector3Int* pos, Vector3Int* vel, CVECTOR* color, int age, ItemInfo* item)
|
||||
{
|
||||
/*
|
||||
SPARKS* sparkle;
|
||||
|
@ -119,7 +121,7 @@ void TriggerChaffSparkles (Vector3Int* pos, Vector3Int* vel, CVECTOR* color,int
|
|||
sparkle->colFadeSpeed = 3;
|
||||
sparkle->fadeToBlack = 5;
|
||||
sparkle->sLife = sparkle->life = 10;
|
||||
sparkle->transType = TransTypeEnum::COLADD;
|
||||
sparkle->transType = BLEND_MODES::BLENDMODE_ADDITIVE;
|
||||
sparkle->dynamic = true;
|
||||
|
||||
sparkle->x = pos->x + (GetRandomDraw() & 7) - 3;
|
||||
|
@ -174,7 +176,7 @@ void TriggerChaffSmoke(Vector3Int* pos, Vector3Int* vel, int speed, bool moving,
|
|||
smoke->sLife = rnd;
|
||||
}
|
||||
|
||||
smoke->transType = TransTypeEnum::COLADD;
|
||||
smoke->blendMode = BLEND_MODES::BLENDMODE_ADDITIVE;
|
||||
|
||||
smoke->x = pos->x + (GetRandomControl() & 7) - 3;
|
||||
smoke->y = pos->y + (GetRandomControl() & 7) - 3;
|
||||
|
|
|
@ -29,15 +29,16 @@ using namespace TEN::Effects::Spark;
|
|||
using namespace TEN::Effects::Environment;
|
||||
using namespace TEN::Math::Random;
|
||||
|
||||
// New particle class
|
||||
Particle Particles[MAX_PARTICLES];
|
||||
ParticleDynamic ParticleDynamics[MAX_PARTICLE_DYNAMICS];
|
||||
|
||||
FX_INFO EffectList[NUM_EFFECTS];
|
||||
|
||||
int NextSpark;
|
||||
int DeadlyBounds[6];
|
||||
SPLASH_SETUP SplashSetup;
|
||||
SPLASH_STRUCT Splashes[MAX_SPLASHES];
|
||||
RIPPLE_STRUCT Ripples[MAX_RIPPLES];
|
||||
SPARKS Sparks[MAX_SPARKS];
|
||||
SP_DYNAMIC SparkDynamics[MAX_SPARKS_DYNAMICS];
|
||||
LaraWeaponType SmokeWeapon;
|
||||
byte SmokeCountL;
|
||||
byte SmokeCountR;
|
||||
|
@ -73,9 +74,9 @@ NODEOFFSET_INFO NodeOffsets[MAX_NODE] =
|
|||
|
||||
void DetatchSpark(int number, SpriteEnumFlag type)
|
||||
{
|
||||
auto* sptr = &Sparks[0];
|
||||
auto* sptr = &Particles[0];
|
||||
|
||||
for (int lp = 0; lp < MAX_SPARKS; lp++, sptr++)
|
||||
for (int lp = 0; lp < MAX_PARTICLES; lp++, sptr++)
|
||||
{
|
||||
if (sptr->on && (sptr->flags & type) && sptr->fxObj == number)
|
||||
{
|
||||
|
@ -115,53 +116,48 @@ void DetatchSpark(int number, SpriteEnumFlag type)
|
|||
}
|
||||
}
|
||||
|
||||
int GetFreeSpark()
|
||||
Particle* GetFreeParticle()
|
||||
{
|
||||
short sparkNumber = NextSpark;
|
||||
int result = -1;
|
||||
|
||||
for (int i = 0; i < MAX_SPARKS; i++)
|
||||
{
|
||||
auto* spark = &Sparks[sparkNumber];
|
||||
// Get first free available spark
|
||||
|
||||
if (!spark->on)
|
||||
for (int i = 0; i < MAX_PARTICLES; i++)
|
||||
{
|
||||
NextSpark = (sparkNumber + 1) & 0x3FF;
|
||||
auto* particle = &Particles[i];
|
||||
|
||||
if (!particle->on)
|
||||
{
|
||||
result = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// No free sparks left, hijack existing one with less possible life
|
||||
|
||||
int life = INT_MAX;
|
||||
if (result == -1)
|
||||
{
|
||||
for (int i = 0; i < MAX_PARTICLES; i++)
|
||||
{
|
||||
auto* particle = &Particles[i];
|
||||
|
||||
if (particle->life < life && particle->dynamic == -1 && !(particle->flags & SP_EXPLOSION))
|
||||
{
|
||||
result = i;
|
||||
life = particle->life;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto* spark = &Particles[result];
|
||||
|
||||
spark->extras = 0;
|
||||
spark->dynamic = -1;
|
||||
spark->def = Objects[ID_DEFAULT_SPRITES].meshIndex;
|
||||
return sparkNumber;
|
||||
}
|
||||
else if (sparkNumber == 1023)
|
||||
sparkNumber = 0;
|
||||
else
|
||||
{
|
||||
spark++;
|
||||
sparkNumber++;
|
||||
}
|
||||
}
|
||||
spark->spriteIndex = Objects[ID_DEFAULT_SPRITES].meshIndex;
|
||||
spark->blendMode = BLEND_MODES::BLENDMODE_ADDITIVE;
|
||||
|
||||
int life = 4095;
|
||||
for (int i = 0; i < MAX_SPARKS; i++)
|
||||
{
|
||||
auto* spark = &Sparks[i];
|
||||
|
||||
if (spark->life < life &&
|
||||
spark->dynamic == -1 &&
|
||||
!(spark->flags & SP_EXPLOSION))
|
||||
{
|
||||
sparkNumber = i;
|
||||
life = spark->life;
|
||||
}
|
||||
}
|
||||
|
||||
NextSpark = (sparkNumber + 1) & 0x3FF;
|
||||
|
||||
auto* spark = &Sparks[sparkNumber];
|
||||
spark->extras = 0;
|
||||
spark->dynamic = -1;
|
||||
spark->def = Objects[ID_DEFAULT_SPRITES].meshIndex;
|
||||
return sparkNumber;
|
||||
return spark;
|
||||
}
|
||||
|
||||
void UpdateSparks()
|
||||
|
@ -174,17 +170,18 @@ void UpdateSparks()
|
|||
DeadlyBounds[4] = LaraItem->Pose.Position.z + bounds->Z1;
|
||||
DeadlyBounds[5] = LaraItem->Pose.Position.z + bounds->Z2;
|
||||
|
||||
for (int i = 0; i < MAX_SPARKS; i++)
|
||||
for (int i = 0; i < MAX_PARTICLES; i++)
|
||||
{
|
||||
auto* spark = &Sparks[i];
|
||||
auto* spark = &Particles[i];
|
||||
|
||||
if (spark->on)
|
||||
{
|
||||
spark->life--;
|
||||
|
||||
if (!spark->life)
|
||||
{
|
||||
if (spark->dynamic != -1)
|
||||
SparkDynamics[spark->dynamic].On = false;
|
||||
ParticleDynamics[spark->dynamic].On = false;
|
||||
|
||||
spark->on = false;
|
||||
continue;
|
||||
|
@ -292,7 +289,9 @@ void UpdateSparks()
|
|||
float alpha = (spark->sLife - spark->life) / (float)spark->sLife;
|
||||
spark->size = lerp(spark->sSize, spark->dSize, alpha);
|
||||
|
||||
if (spark->flags & SP_FIRE && !Lara.Burn || spark->flags & SP_DAMAGE)
|
||||
if ((spark->flags & SP_FIRE && !Lara.Burn) ||
|
||||
(spark->flags & SP_DAMAGE) ||
|
||||
(spark->flags & SP_POISON))
|
||||
{
|
||||
ds = spark->size * (spark->scalar / 2.0);
|
||||
|
||||
|
@ -304,8 +303,12 @@ void UpdateSparks()
|
|||
{
|
||||
if (spark->flags & SP_FIRE)
|
||||
LaraBurn(LaraItem);
|
||||
else
|
||||
|
||||
if (spark->flags & SP_DAMAGE)
|
||||
LaraItem->HitPoints -= 2;
|
||||
|
||||
if (spark->flags & SP_POISON)
|
||||
Lara.PoisonPotency += 5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -313,13 +316,13 @@ void UpdateSparks()
|
|||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_SPARKS; i++)
|
||||
for (int i = 0; i < MAX_PARTICLES; i++)
|
||||
{
|
||||
auto* spark = &Sparks[i];
|
||||
auto* spark = &Particles[i];
|
||||
|
||||
if (spark->on && spark->dynamic != -1)
|
||||
{
|
||||
auto* dynsp = &SparkDynamics[spark->dynamic];
|
||||
auto* dynsp = &ParticleDynamics[spark->dynamic];
|
||||
if (dynsp->Flags & 3)
|
||||
{
|
||||
int random = GetRandomControl();
|
||||
|
@ -401,7 +404,7 @@ void TriggerCyborgSpark(int x, int y, int z, short xv, short yv, short zv)
|
|||
|
||||
if (dx >= -16384 && dx <= 16384 && dz >= -16384 && dz <= 16384)
|
||||
{
|
||||
auto* spark = &Sparks[GetFreeSpark()];
|
||||
auto* spark = GetFreeParticle();
|
||||
|
||||
int random = rand();
|
||||
|
||||
|
@ -416,7 +419,7 @@ void TriggerCyborgSpark(int x, int y, int z, short xv, short yv, short zv)
|
|||
spark->dB = -64 - ((random & 0x7F) + 64);
|
||||
spark->life = 10;
|
||||
spark->sLife = 10;
|
||||
spark->transType = TransTypeEnum::COLADD;
|
||||
spark->blendMode = BLEND_MODES::BLENDMODE_ADDITIVE;
|
||||
spark->friction = 34;
|
||||
spark->scalar = 1;
|
||||
spark->x = (random & 7) + x - 3;
|
||||
|
@ -445,7 +448,7 @@ void TriggerExplosionBubbles(int x, int y, int z, short roomNumber)
|
|||
|
||||
if (dx >= -ANGLE(90.0f) && dx <= ANGLE(90.0f) && dz >= -ANGLE(90.0f) && dz <= ANGLE(90.0f))
|
||||
{
|
||||
auto* spark = &Sparks[GetFreeSpark()];
|
||||
auto* spark = GetFreeParticle();
|
||||
|
||||
spark->sR = -128;
|
||||
spark->dR = -128;
|
||||
|
@ -458,7 +461,7 @@ void TriggerExplosionBubbles(int x, int y, int z, short roomNumber)
|
|||
spark->sB = 0;
|
||||
spark->colFadeSpeed = 8;
|
||||
spark->fadeToBlack = 12;
|
||||
spark->transType = TransTypeEnum::COLADD;
|
||||
spark->blendMode = BLEND_MODES::BLENDMODE_ADDITIVE;
|
||||
spark->x = x;
|
||||
spark->y = y;
|
||||
spark->z = z;
|
||||
|
@ -467,7 +470,7 @@ void TriggerExplosionBubbles(int x, int y, int z, short roomNumber)
|
|||
spark->zVel = 0;
|
||||
spark->friction = 0;
|
||||
spark->flags = SP_UNDERWEXP | SP_DEF | SP_SCALE;
|
||||
spark->def = Objects[ID_DEFAULT_SPRITES].meshIndex + 13;
|
||||
spark->spriteIndex = Objects[ID_DEFAULT_SPRITES].meshIndex + 13;
|
||||
spark->scalar = 3;
|
||||
spark->gravity = 0;
|
||||
spark->maxYvel = 0;
|
||||
|
@ -490,7 +493,7 @@ void TriggerExplosionBubbles(int x, int y, int z, short roomNumber)
|
|||
|
||||
void TriggerExplosionSmokeEnd(int x, int y, int z, int uw)
|
||||
{
|
||||
auto* spark = &Sparks[GetFreeSpark()];
|
||||
auto* spark = GetFreeParticle();
|
||||
|
||||
spark->on = true;
|
||||
|
||||
|
@ -518,9 +521,9 @@ void TriggerExplosionSmokeEnd(int x, int y, int z, int uw)
|
|||
spark->life = spark->sLife= (GetRandomControl() & 0x1F) + 96;
|
||||
|
||||
if (uw)
|
||||
spark->transType = TransTypeEnum::COLADD;
|
||||
spark->blendMode = BLEND_MODES::BLENDMODE_ADDITIVE;
|
||||
else
|
||||
spark->transType = TransTypeEnum::COLSUB;
|
||||
spark->blendMode = BLEND_MODES::BLENDMODE_SUBTRACTIVE;
|
||||
|
||||
spark->x = (GetRandomControl() & 0x1F) + x - 16;
|
||||
spark->y = (GetRandomControl() & 0x1F) + y - 16;
|
||||
|
@ -571,7 +574,7 @@ void TriggerExplosionSmoke(int x, int y, int z, int uw)
|
|||
|
||||
if (dx >= -16384 && dx <= 16384 && dz >= -16384 && dz <= 16384)
|
||||
{
|
||||
auto* spark = &Sparks[GetFreeSpark()];
|
||||
auto* spark = GetFreeParticle();
|
||||
|
||||
spark->sR = -112;
|
||||
spark->sG = -112;
|
||||
|
@ -582,7 +585,7 @@ void TriggerExplosionSmoke(int x, int y, int z, int uw)
|
|||
spark->dB = 64;
|
||||
spark->colFadeSpeed = 2;
|
||||
spark->fadeToBlack = 8;
|
||||
spark->transType = TransTypeEnum::COLSUB;
|
||||
spark->blendMode = BLEND_MODES::BLENDMODE_SUBTRACTIVE;
|
||||
spark->life = spark->sLife = (GetRandomControl() & 3) + 10;
|
||||
spark->x = (GetRandomControl() & 0x1FF) + x - 256;
|
||||
spark->y = (GetRandomControl() & 0x1FF) + y - 256;
|
||||
|
@ -616,7 +619,7 @@ void TriggerExplosionSmoke(int x, int y, int z, int uw)
|
|||
if (dx < -16384 || dx > 16384 || dz < -16384 || dz > 16384)
|
||||
return;
|
||||
|
||||
auto* spark = &Sparks[GetFreeSpark()];
|
||||
auto* spark = GetFreeParticle();
|
||||
|
||||
spark->on = true;
|
||||
|
||||
|
@ -698,7 +701,7 @@ void TriggerExplosionSmoke(int x, int y, int z, int uw)
|
|||
spark->sLife = spark->life = (GetRandomControl() & 3) + 28;
|
||||
}
|
||||
|
||||
spark->transType = TransTypeEnum::COLADD;
|
||||
spark->blendMode = BLEND_MODES::BLENDMODE_ADDITIVE;
|
||||
|
||||
if (fxObj == -1)
|
||||
{
|
||||
|
@ -811,7 +814,7 @@ void TriggerSuperJetFlame(ItemInfo* item, int yvel, int deadly)
|
|||
if (dx >= -16384 && dx <= 16384 && dz >= -16384 && dz <= 16384)
|
||||
{
|
||||
int size = (GetRandomControl() & 0x1FF) - yvel;
|
||||
auto* sptr = &Sparks[GetFreeSpark()];
|
||||
auto* sptr = GetFreeParticle();
|
||||
|
||||
if (size < 512)
|
||||
size = 512;
|
||||
|
@ -824,7 +827,7 @@ void TriggerSuperJetFlame(ItemInfo* item, int yvel, int deadly)
|
|||
sptr->dB = 32;
|
||||
sptr->colFadeSpeed = 8;
|
||||
sptr->fadeToBlack = 8;
|
||||
sptr->transType = TransTypeEnum::COLADD;
|
||||
sptr->blendMode = BLEND_MODES::BLENDMODE_ADDITIVE;
|
||||
sptr->life = sptr->sLife = (size >> 9) + (GetRandomControl() & 7) + 16;
|
||||
sptr->x = (GetRandomControl() & 0x1F) + item->Pose.Position.x - 16;
|
||||
sptr->y = (GetRandomControl() & 0x1F) + item->Pose.Position.y - 16;
|
||||
|
@ -1087,7 +1090,7 @@ void Richochet(PHD_3DPOS* pos)
|
|||
target.y = pos->Position.y;
|
||||
target.z = pos->Position.z;
|
||||
TriggerRicochetSpark(&target, angle / 16, 3, 0);
|
||||
SoundEffect(SFX_TR4_LARA_RICOCHET, pos);
|
||||
SoundEffect(SFX_TR4_WEAPON_RICOCHET, pos);
|
||||
}
|
||||
|
||||
void ControlWaterfallMist(short itemNumber) // ControlWaterfallMist
|
||||
|
@ -1103,7 +1106,6 @@ void ControlWaterfallMist(short itemNumber) // ControlWaterfallMist
|
|||
|
||||
void TriggerWaterfallMist(int x, int y, int z, int angle)
|
||||
{
|
||||
SPARKS* spark;
|
||||
int dh = 0;
|
||||
int ang1 = angle;
|
||||
int ang2 = angle;
|
||||
|
@ -1112,7 +1114,7 @@ void TriggerWaterfallMist(int x, int y, int z, int angle)
|
|||
// CHECK THIS LOOP CONDITIONS
|
||||
for (ang1 = angle; ; ang1 *= 2)
|
||||
{
|
||||
spark = &Sparks[GetFreeSpark()];
|
||||
auto* spark = GetFreeParticle();
|
||||
spark->on = 1;
|
||||
spark->sR = 64;
|
||||
spark->sG = 64;
|
||||
|
@ -1121,7 +1123,7 @@ void TriggerWaterfallMist(int x, int y, int z, int angle)
|
|||
spark->dG = 64;
|
||||
spark->dB = 64;
|
||||
spark->colFadeSpeed = 1;
|
||||
spark->transType = TransTypeEnum::COLADD;
|
||||
spark->blendMode = BLEND_MODES::BLENDMODE_ADDITIVE;
|
||||
spark->life = spark->sLife = (GetRandomControl() & 3) + 6;
|
||||
spark->fadeToBlack = spark->life - 4;
|
||||
dl = ((dh + (GlobalCounter << 6)) % 1536) + (GetRandomControl() & 0x3F) - 32;
|
||||
|
@ -1146,7 +1148,7 @@ void TriggerWaterfallMist(int x, int y, int z, int angle)
|
|||
break;
|
||||
}
|
||||
|
||||
spark = &Sparks[GetFreeSpark()];
|
||||
auto* spark = GetFreeParticle();
|
||||
spark->on = 1;
|
||||
spark->sR = 96;
|
||||
spark->sG = 96;
|
||||
|
@ -1155,7 +1157,7 @@ void TriggerWaterfallMist(int x, int y, int z, int angle)
|
|||
spark->dG = 96;
|
||||
spark->dB = 96;
|
||||
spark->colFadeSpeed = 1;
|
||||
spark->transType = TransTypeEnum::COLADD;
|
||||
spark->blendMode = BLEND_MODES::BLENDMODE_ADDITIVE;
|
||||
spark->life = spark->sLife = (GetRandomControl() & 3) + 6;
|
||||
spark->fadeToBlack = spark->life - 1;
|
||||
dl = GetRandomControl() % 1408 + 64;
|
||||
|
@ -1168,7 +1170,7 @@ void TriggerWaterfallMist(int x, int y, int z, int angle)
|
|||
spark->flags = 10;
|
||||
spark->yVel = GetRandomControl() & 0x100 + (GetRandomControl() & 0x7F) + 128;
|
||||
spark->scalar = 2;
|
||||
spark->def = Objects[ID_DEFAULT_SPRITES].meshIndex + 17;
|
||||
spark->spriteIndex = Objects[ID_DEFAULT_SPRITES].meshIndex + 17;
|
||||
spark->gravity = 0;
|
||||
spark->maxYvel = 0;
|
||||
spark->sSize = spark->size = (GetRandomControl() & 7) + 8;
|
||||
|
@ -1280,7 +1282,7 @@ void Splash(ItemInfo* item)
|
|||
|
||||
void TriggerRocketFlame(int x, int y, int z, int xv, int yv, int zv, int itemNumber)
|
||||
{
|
||||
auto* sptr = &Sparks[GetFreeSpark()];
|
||||
auto* sptr = GetFreeParticle();
|
||||
|
||||
sptr->on = true;
|
||||
sptr->sR = 48 + (GetRandomControl() & 31);
|
||||
|
@ -1294,7 +1296,7 @@ void TriggerRocketFlame(int x, int y, int z, int xv, int yv, int zv, int itemNum
|
|||
sptr->colFadeSpeed = 12 + (GetRandomControl() & 3);
|
||||
sptr->fadeToBlack = 12;
|
||||
sptr->sLife = sptr->life = (GetRandomControl() & 3) + 28;
|
||||
sptr->transType = TransTypeEnum::COLADD;
|
||||
sptr->blendMode = BLEND_MODES::BLENDMODE_ADDITIVE;
|
||||
sptr->extras = 0;
|
||||
sptr->dynamic = -1;
|
||||
|
||||
|
@ -1328,7 +1330,7 @@ void TriggerRocketFlame(int x, int y, int z, int xv, int yv, int zv, int itemNum
|
|||
sptr->maxYvel = 0;
|
||||
|
||||
// TODO: right sprite
|
||||
sptr->def = Objects[ID_DEFAULT_SPRITES].meshIndex;
|
||||
sptr->spriteIndex = Objects[ID_DEFAULT_SPRITES].meshIndex;
|
||||
sptr->scalar = 2;
|
||||
|
||||
int size = (GetRandomControl() & 7) + 32;
|
||||
|
@ -1337,7 +1339,7 @@ void TriggerRocketFlame(int x, int y, int z, int xv, int yv, int zv, int itemNum
|
|||
|
||||
void TriggerRocketFire(int x, int y, int z)
|
||||
{
|
||||
auto* sptr = &Sparks[GetFreeSpark()];
|
||||
auto* sptr = GetFreeParticle();
|
||||
|
||||
sptr->on = true;
|
||||
|
||||
|
@ -1350,7 +1352,7 @@ void TriggerRocketFire(int x, int y, int z)
|
|||
sptr->colFadeSpeed = 4 + (GetRandomControl() & 3);
|
||||
sptr->fadeToBlack = 12;
|
||||
sptr->sLife = sptr->life = (GetRandomControl() & 3) + 20;
|
||||
sptr->transType = TransTypeEnum::COLADD;
|
||||
sptr->blendMode = BLEND_MODES::BLENDMODE_ADDITIVE;
|
||||
sptr->extras = 0;
|
||||
sptr->dynamic = -1;
|
||||
|
||||
|
@ -1376,7 +1378,7 @@ void TriggerRocketFire(int x, int y, int z)
|
|||
sptr->flags = SP_SCALE | SP_DEF | SP_EXPDEF;
|
||||
|
||||
// TODO: right sprite
|
||||
sptr->def = Objects[ID_DEFAULT_SPRITES].meshIndex;
|
||||
sptr->spriteIndex = Objects[ID_DEFAULT_SPRITES].meshIndex;
|
||||
sptr->scalar = 1;
|
||||
sptr->gravity = -(GetRandomControl() & 3) - 4;
|
||||
sptr->maxYvel = -(GetRandomControl() & 3) - 4;
|
||||
|
@ -1389,7 +1391,7 @@ void TriggerRocketFire(int x, int y, int z)
|
|||
|
||||
void TriggerRocketSmoke(int x, int y, int z, int bodyPart)
|
||||
{
|
||||
/*SPARKS* sptr = &Sparks[GetFreeSpark()];
|
||||
/*auto* sptr = GetFreeParticle();
|
||||
|
||||
sptr->on = true;
|
||||
sptr->sR = 0;
|
||||
|
@ -1403,7 +1405,7 @@ void TriggerRocketSmoke(int x, int y, int z, int bodyPart)
|
|||
sptr->colFadeSpeed = 4 + (GetRandomControl() & 3);
|
||||
sptr->fadeToBlack = 12;
|
||||
sptr->sLife = sptr->life = (GetRandomControl() & 3) + 20;
|
||||
sptr->transType = TransTypeEnum::COLADD;
|
||||
sptr->blendMode = BLEND_MODES::BLENDMODE_ADDITIVE;
|
||||
sptr->extras = 0;
|
||||
sptr->dynamic = -1;
|
||||
|
||||
|
@ -1457,7 +1459,7 @@ void TriggerFlashSmoke(int x, int y, int z, short roomNumber)
|
|||
spark->dShade = -128;
|
||||
spark->colFadeSpeed = 4;
|
||||
spark->fadeToBlack = 16;
|
||||
spark->transType = TransTypeEnum::COLADD;
|
||||
spark->blendMode = BLEND_MODES::BLENDMODE_ADDITIVE;
|
||||
spark->life = spark->sLife = (GetRandomControl() & 0xF) + 64;
|
||||
spark->x = (GetRandomControl() & 0x1F) + x - 16;
|
||||
spark->y = (GetRandomControl() & 0x1F) + y - 16;
|
||||
|
@ -1502,7 +1504,7 @@ void TriggerFireFlame(int x, int y, int z, int fxObj, int type)
|
|||
|
||||
if (dx >= -16384 && dx <= 16384 && dz >= -16384 && dz <= 16384)
|
||||
{
|
||||
auto* spark = &Sparks[GetFreeSpark()];
|
||||
auto* spark = GetFreeParticle();
|
||||
|
||||
spark->on = true;
|
||||
|
||||
|
@ -1560,7 +1562,7 @@ void TriggerFireFlame(int x, int y, int z, int fxObj, int type)
|
|||
spark->life = spark->sLife = (GetRandomControl() & 3) + 18;
|
||||
}
|
||||
|
||||
spark->transType = TransTypeEnum::COLADD;
|
||||
spark->blendMode = BLEND_MODES::BLENDMODE_ADDITIVE;
|
||||
|
||||
if (fxObj != -1)
|
||||
{
|
||||
|
@ -1705,7 +1707,7 @@ void TriggerMetalSparks(int x, int y, int z, int xv, int yv, int zv, int additio
|
|||
{
|
||||
int r = rand();
|
||||
|
||||
auto* spark = &Sparks[GetFreeSpark()];
|
||||
auto* spark = GetFreeParticle();
|
||||
|
||||
spark->dG = (r & 0x7F) + 64;
|
||||
spark->dB = -64 - (r & 0x7F) + 64;
|
||||
|
@ -1720,7 +1722,7 @@ void TriggerMetalSparks(int x, int y, int z, int xv, int yv, int zv, int additio
|
|||
spark->colFadeSpeed = 3;
|
||||
spark->fadeToBlack = 5;
|
||||
spark->y = ((r >> 3) & 7) + y - 3;
|
||||
spark->transType = TransTypeEnum::COLADD;
|
||||
spark->blendMode = BLEND_MODES::BLENDMODE_ADDITIVE;
|
||||
spark->friction = 34;
|
||||
spark->scalar = 1;
|
||||
spark->z = ((r >> 6) & 7) + z - 3;
|
||||
|
@ -1737,12 +1739,12 @@ void TriggerMetalSparks(int x, int y, int z, int xv, int yv, int zv, int additio
|
|||
if (additional)
|
||||
{
|
||||
r = rand();
|
||||
spark = &Sparks[GetFreeSpark()];
|
||||
spark = GetFreeParticle();
|
||||
spark->on = 1;
|
||||
spark->sR = spark->dR >> 1;
|
||||
spark->sG = spark->dG >> 1;
|
||||
spark->fadeToBlack = 4;
|
||||
spark->transType = TransTypeEnum::COLADD;
|
||||
spark->blendMode = BLEND_MODES::BLENDMODE_ADDITIVE;
|
||||
spark->colFadeSpeed = (r & 3) + 8;
|
||||
spark->sB = spark->dB >> 1;
|
||||
spark->dR = 32;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
#include "Specific/phd_global.h"
|
||||
#include "Renderer/Renderer11Enums.h"
|
||||
|
||||
enum class LaraWeaponType;
|
||||
struct ItemInfo;
|
||||
|
@ -33,23 +34,8 @@ enum SpriteEnumFlag
|
|||
SP_DAMAGE = 0x0400,
|
||||
SP_UNDERWEXP = 0x0800,
|
||||
SP_NODEATTACH = 0x1000,
|
||||
SP_PLASMAEXP = 0x2000
|
||||
};
|
||||
|
||||
enum class TransTypeEnum
|
||||
{
|
||||
NOTRANS,
|
||||
SEMITRANS,
|
||||
COLADD,
|
||||
COLSUB,
|
||||
WEIRD
|
||||
};
|
||||
|
||||
enum FireSizeEnum
|
||||
{
|
||||
SP_NORMALFIRE,
|
||||
SP_SMALLFIRE,
|
||||
SP_BIGFIRE
|
||||
SP_PLASMAEXP = 0x2000,
|
||||
SP_POISON = 0x4000
|
||||
};
|
||||
|
||||
struct FX_INFO
|
||||
|
@ -98,7 +84,7 @@ struct RIPPLE_STRUCT
|
|||
unsigned char init;
|
||||
};
|
||||
|
||||
struct SPARKS
|
||||
struct Particle
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
|
@ -114,24 +100,24 @@ struct SPARKS
|
|||
float size;
|
||||
unsigned char friction;
|
||||
unsigned char scalar;
|
||||
unsigned char def;
|
||||
unsigned char spriteIndex;
|
||||
signed char rotAdd;
|
||||
signed char maxYvel;
|
||||
bool on;
|
||||
byte sR;
|
||||
byte sG;
|
||||
byte sB;
|
||||
byte dR;
|
||||
byte dG;
|
||||
byte dB;
|
||||
byte r;
|
||||
byte g;
|
||||
byte b;
|
||||
unsigned char sR;
|
||||
unsigned char sG;
|
||||
unsigned char sB;
|
||||
unsigned char dR;
|
||||
unsigned char dG;
|
||||
unsigned char dB;
|
||||
unsigned char r;
|
||||
unsigned char g;
|
||||
unsigned char b;
|
||||
unsigned char colFadeSpeed;
|
||||
unsigned char fadeToBlack;
|
||||
unsigned char sLife;
|
||||
unsigned char life;
|
||||
TransTypeEnum transType;
|
||||
int sLife;
|
||||
int life;
|
||||
BLEND_MODES blendMode;
|
||||
unsigned char extras;
|
||||
signed char dynamic;
|
||||
unsigned char fxObj;
|
||||
|
@ -160,7 +146,7 @@ struct SPLASH_STRUCT
|
|||
bool isActive;
|
||||
};
|
||||
|
||||
struct SP_DYNAMIC
|
||||
struct ParticleDynamic
|
||||
{
|
||||
byte On;
|
||||
byte Falloff;
|
||||
|
@ -176,29 +162,37 @@ constexpr auto SD_UWEXPLOSION = 2;
|
|||
|
||||
#define MAX_NODE 23
|
||||
#define MAX_DYNAMICS 64
|
||||
#define MAX_SPARKS 1024
|
||||
#define MAX_RIPPLES 256
|
||||
#define MAX_SPLASHES 8
|
||||
#define MAX_SPARKS_DYNAMICS 8
|
||||
#define NUM_EFFECTS 256
|
||||
extern int NextSpark;
|
||||
|
||||
extern int DeadlyBounds[6];
|
||||
|
||||
|
||||
// New particle class
|
||||
|
||||
constexpr auto MAX_PARTICLES = 1024;
|
||||
constexpr auto MAX_PARTICLE_DYNAMICS = 8;
|
||||
extern Particle Particles[MAX_PARTICLES];
|
||||
extern ParticleDynamic ParticleDynamics[MAX_PARTICLE_DYNAMICS];
|
||||
|
||||
extern SPLASH_SETUP SplashSetup;
|
||||
extern SPLASH_STRUCT Splashes[MAX_SPLASHES];
|
||||
extern RIPPLE_STRUCT Ripples[MAX_RIPPLES];
|
||||
extern SPARKS Sparks[MAX_SPARKS];
|
||||
extern SP_DYNAMIC SparkDynamics[MAX_SPARKS_DYNAMICS];
|
||||
|
||||
extern LaraWeaponType SmokeWeapon;
|
||||
extern byte SmokeCountL;
|
||||
extern byte SmokeCountR;
|
||||
extern int SplashCount;
|
||||
|
||||
extern Vector3Int NodeVectors[MAX_NODE];
|
||||
extern NODEOFFSET_INFO NodeOffsets[MAX_NODE];
|
||||
|
||||
extern FX_INFO EffectList[NUM_EFFECTS];
|
||||
|
||||
Particle* GetFreeParticle();
|
||||
|
||||
void DetatchSpark(int num, SpriteEnumFlag type);
|
||||
int GetFreeSpark();
|
||||
void UpdateSparks();
|
||||
void TriggerRicochetSpark(GameVector* pos, short angle, int num, int unk);
|
||||
void TriggerCyborgSpark(int x, int y, int z, short xv, short yv, short zv);
|
||||
|
|
|
@ -58,12 +58,12 @@ namespace Footprints {
|
|||
if (result.Position.Bridge >= 0)
|
||||
return;
|
||||
|
||||
auto fx = SOUND_EFFECTS::SFX_TR4_LARA_FEET;
|
||||
auto fx = SOUND_EFFECTS::SFX_TR4_LARA_FOOTSTEPS;
|
||||
// Choose material for footstep sound
|
||||
switch (floor->Material)
|
||||
{
|
||||
case FLOOR_MATERIAL::Concrete:
|
||||
fx = SOUND_EFFECTS::SFX_TR4_LARA_FEET;
|
||||
fx = SOUND_EFFECTS::SFX_TR4_LARA_FOOTSTEPS;
|
||||
break;
|
||||
|
||||
case FLOOR_MATERIAL::Grass:
|
||||
|
@ -107,7 +107,7 @@ namespace Footprints {
|
|||
break;
|
||||
|
||||
case FLOOR_MATERIAL::Stone:
|
||||
fx = SOUND_EFFECTS::SFX_TR4_LARA_FEET;
|
||||
fx = SOUND_EFFECTS::SFX_TR4_LARA_FOOTSTEPS;
|
||||
break;
|
||||
|
||||
case FLOOR_MATERIAL::Water:
|
||||
|
@ -152,7 +152,7 @@ namespace Footprints {
|
|||
}
|
||||
|
||||
// HACK: must be here until reference wad2 is revised
|
||||
if (fx != SOUND_EFFECTS::SFX_TR4_LARA_FEET)
|
||||
if (fx != SOUND_EFFECTS::SFX_TR4_LARA_FOOTSTEPS)
|
||||
SoundEffect(fx, &item->Pose);
|
||||
|
||||
if (floor->Material != FLOOR_MATERIAL::Sand &&
|
||||
|
@ -209,9 +209,9 @@ namespace Footprints {
|
|||
footprint.Position[1] = p1;
|
||||
footprint.Position[2] = p2;
|
||||
footprint.Position[3] = p3;
|
||||
footprint.LifeStartFading = 30 * 10;
|
||||
footprint.StartOpacity = 0.25f;
|
||||
footprint.Life = 30 * 20;
|
||||
footprint.LifeStartFading = FPS * 10;
|
||||
footprint.Life = FPS * 20;
|
||||
footprint.Active = true;
|
||||
footprint.RightFoot = rightFoot;
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "Game/effects/smoke.h"
|
||||
#include "Game/items.h"
|
||||
#include "Game/Lara/lara.h"
|
||||
#include "Game/Lara/lara_helpers.h"
|
||||
#include "Specific/level.h"
|
||||
|
||||
using namespace TEN::Effects::Smoke;
|
||||
|
@ -19,7 +20,7 @@ namespace TEN::Effects::Lara
|
|||
if (!item->Data.is<LaraInfo*>())
|
||||
return;
|
||||
|
||||
auto lara = (LaraInfo*&)item->Data;
|
||||
auto* lara = GetLaraInfo(item);
|
||||
|
||||
if (!lara->Burn && !lara->BurnSmoke)
|
||||
{
|
||||
|
@ -37,7 +38,7 @@ namespace TEN::Effects::Lara
|
|||
if (!item->Data.is<LaraInfo*>())
|
||||
return;
|
||||
|
||||
auto lara = (LaraInfo*&)item->Data;
|
||||
auto* lara = GetLaraInfo(item);
|
||||
|
||||
if (item->HitPoints >= 0 && lara->Control.WaterStatus != WaterStatus::FlyCheat)
|
||||
{
|
||||
|
@ -62,7 +63,7 @@ namespace TEN::Effects::Lara
|
|||
if (!item->Data.is<LaraInfo*>())
|
||||
return;
|
||||
|
||||
auto lara = (LaraInfo*&)item->Data;
|
||||
auto* lara = GetLaraInfo(item);
|
||||
|
||||
if (lara->Control.WaterStatus == WaterStatus::Underwater || item->HitPoints <= 0)
|
||||
return;
|
||||
|
|
|
@ -380,7 +380,7 @@ namespace TEN::Effects::Lightning
|
|||
|
||||
void TriggerLightningGlow(int x, int y, int z, byte size, byte r, byte g, byte b)
|
||||
{
|
||||
SPARKS* spark = &Sparks[GetFreeSpark()];
|
||||
auto* spark = GetFreeParticle();
|
||||
|
||||
spark->dG = g;
|
||||
spark->sG = g;
|
||||
|
@ -389,7 +389,7 @@ namespace TEN::Effects::Lightning
|
|||
spark->dR = r;
|
||||
spark->sR = r;
|
||||
spark->colFadeSpeed = 2;
|
||||
spark->transType = TransTypeEnum::COLADD;
|
||||
spark->blendMode = BLEND_MODES::BLENDMODE_ADDITIVE;
|
||||
spark->on = 1;
|
||||
spark->dB = b;
|
||||
spark->sB = b;
|
||||
|
@ -403,7 +403,7 @@ namespace TEN::Effects::Lightning
|
|||
spark->flags = SP_DEF | SP_SCALE;
|
||||
spark->scalar = 3;
|
||||
spark->maxYvel = 0;
|
||||
spark->def = Objects[ID_MISC_SPRITES].meshIndex;
|
||||
spark->spriteIndex = Objects[ID_MISC_SPRITES].meshIndex;
|
||||
spark->gravity = 0;
|
||||
spark->dSize = spark->sSize = spark->size = size + (GetRandomControl() & 3);
|
||||
}
|
||||
|
|
|
@ -201,7 +201,154 @@ void TriggerGlobalFireFlame()
|
|||
spark->dSize = spark->size;
|
||||
}
|
||||
|
||||
void keep_those_fires_burning()
|
||||
void TriggerPilotFlame(int itemNum, int nodeIndex)
|
||||
{
|
||||
auto* item = &g_Level.Items[itemNum];
|
||||
|
||||
int dx = Camera.pos.x - item->Pose.Position.x;
|
||||
int dz = Camera.pos.z - item->Pose.Position.z;
|
||||
if (dx < -SECTOR(16) || dx > SECTOR(16) || dz < -SECTOR(16) || dz > SECTOR(16))
|
||||
return;
|
||||
|
||||
auto* spark = GetFreeParticle();
|
||||
|
||||
spark->on = 1;
|
||||
spark->sR = 48 + (GetRandomControl() & 31);
|
||||
spark->sG = spark->sR;
|
||||
spark->sB = 192 + (GetRandomControl() & 63);
|
||||
|
||||
spark->dR = 192 + (GetRandomControl() & 63);
|
||||
spark->dG = 128 + (GetRandomControl() & 63);
|
||||
spark->dB = 32;
|
||||
|
||||
spark->colFadeSpeed = 12 + (GetRandomControl() & 3);
|
||||
spark->fadeToBlack = 4;
|
||||
spark->sLife = spark->life = (GetRandomControl() & 3) + 20;
|
||||
spark->blendMode = BLEND_MODES::BLENDMODE_ADDITIVE;
|
||||
spark->extras = 0;
|
||||
spark->dynamic = -1;
|
||||
spark->fxObj = itemNum;
|
||||
|
||||
spark->x = (GetRandomControl() & 31) - 16;
|
||||
spark->y = (GetRandomControl() & 31) - 16;
|
||||
spark->z = (GetRandomControl() & 31) - 16;
|
||||
|
||||
spark->xVel = (GetRandomControl() & 31) - 16;
|
||||
spark->yVel = -(GetRandomControl() & 3);
|
||||
spark->zVel = (GetRandomControl() & 31) - 16;
|
||||
|
||||
spark->flags = SP_SCALE | SP_DEF | SP_EXPDEF | SP_ITEM | SP_NODEATTACH;
|
||||
spark->nodeNumber = nodeIndex;
|
||||
spark->friction = 4;
|
||||
spark->gravity = -(GetRandomControl() & 3) - 2;
|
||||
spark->maxYvel = -(GetRandomControl() & 3) - 4;
|
||||
//spark->def = Objects[EXPLOSION1].mesh_index;
|
||||
spark->scalar = 0;
|
||||
int size = (GetRandomControl() & 7) + 32;
|
||||
spark->size = size / 2;
|
||||
spark->dSize = size;
|
||||
}
|
||||
|
||||
Particle* SetupPoisonSpark(Vector3 color)
|
||||
{
|
||||
auto* spark = GetFreeParticle();
|
||||
|
||||
bool rMax = color.x > color.y && color.x > color.z;
|
||||
bool gMax = color.y > color.x && color.y > color.z;
|
||||
bool bMax = color.z > color.x && color.z > color.y;
|
||||
|
||||
char seed = (GetRandomControl() & 0x1F) + 220;
|
||||
|
||||
spark->sR = (rMax ? seed : 255) * (color.x * 0.4);
|
||||
spark->sG = (gMax ? seed : 255) * (color.y * 0.4);
|
||||
spark->sB = (bMax ? seed : 255) * (color.z * 0.4);
|
||||
spark->dR = 255 * color.x;
|
||||
spark->dG = 255 * color.y;
|
||||
spark->dB = 255 * color.z;
|
||||
spark->colFadeSpeed = 14;
|
||||
spark->fadeToBlack = 8;
|
||||
spark->blendMode = BLEND_MODES::BLENDMODE_SCREEN;
|
||||
|
||||
return spark;
|
||||
}
|
||||
|
||||
Particle* SetupFireSpark()
|
||||
{
|
||||
auto* spark = GetFreeParticle();
|
||||
|
||||
spark->sR = (GetRandomControl() & 0x1F) + 48;
|
||||
spark->sG = 38;
|
||||
spark->sB = 255;
|
||||
spark->dR = (GetRandomControl() & 0x3F) - 64;
|
||||
spark->dG = (GetRandomControl() & 0x3F) + -128;
|
||||
spark->dB = 32;
|
||||
spark->colFadeSpeed = 12;
|
||||
spark->fadeToBlack = 8;
|
||||
spark->blendMode = BLEND_MODES::BLENDMODE_ADDITIVE;
|
||||
|
||||
return spark;
|
||||
}
|
||||
|
||||
void AttachAndCreateSpark(Particle* spark, ItemInfo* item, int meshIndex, Vector3Int offset, Vector3Int speed)
|
||||
{
|
||||
auto pos1 = Vector3Int(-4, -30, -4) + offset;
|
||||
GetJointAbsPosition(item, &pos1, meshIndex);
|
||||
|
||||
spark->x = (GetRandomControl() & 0x1F) + pos1.x - 16;
|
||||
spark->y = (GetRandomControl() & 0x1F) + pos1.y - 16;
|
||||
spark->z = (GetRandomControl() & 0x1F) + pos1.z - 16;
|
||||
|
||||
auto pos2 = Vector3Int(-4, -30, -4) + offset + speed;
|
||||
GetJointAbsPosition(item, &pos2, meshIndex);
|
||||
|
||||
int v = (GetRandomControl() & 0x3F) + 192;
|
||||
|
||||
spark->life = spark->sLife = v / 6;
|
||||
|
||||
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 = SP_FIRE | SP_SCALE | SP_DEF | SP_ROTATE | SP_EXPDEF;
|
||||
|
||||
spark->scalar = 3;
|
||||
spark->dSize = (v * ((GetRandomControl() & 7) + 60)) / 256;
|
||||
spark->sSize = spark->dSize / 4;
|
||||
spark->size = spark->dSize / 2;
|
||||
|
||||
spark->on = 1;
|
||||
}
|
||||
|
||||
void ThrowFire(int itemNum, int meshIndex, Vector3Int offset, Vector3Int speed)
|
||||
{
|
||||
auto* item = &g_Level.Items[itemNum];
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
auto* spark = SetupFireSpark();
|
||||
AttachAndCreateSpark(spark, item, meshIndex, offset, speed);
|
||||
|
||||
spark->flags = SP_FIRE | SP_SCALE | SP_DEF | SP_ROTATE | SP_EXPDEF;
|
||||
}
|
||||
}
|
||||
|
||||
void ThrowPoison(int itemNum, int meshIndex, Vector3Int offset, Vector3Int speed, Vector3 color)
|
||||
{
|
||||
auto* item = &g_Level.Items[itemNum];
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
auto* spark = SetupPoisonSpark(color);
|
||||
AttachAndCreateSpark(spark, item, meshIndex, offset, speed);
|
||||
|
||||
spark->flags = SP_POISON | SP_SCALE | SP_DEF | SP_ROTATE | SP_EXPDEF;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateFireProgress()
|
||||
{
|
||||
TriggerGlobalStaticFlame();
|
||||
if (!(Wibble & 0xF))
|
||||
|
@ -212,7 +359,7 @@ void keep_those_fires_burning()
|
|||
}
|
||||
}
|
||||
|
||||
void AddFire(int x, int y, int z, char size, short roomNum, short on)
|
||||
void AddFire(int x, int y, int z, short roomNum, float size, short fade)
|
||||
{
|
||||
FIRE_LIST* fptr = &Fires[0];
|
||||
int i = 0;
|
||||
|
@ -223,8 +370,8 @@ void AddFire(int x, int y, int z, char size, short roomNum, short on)
|
|||
return;
|
||||
}
|
||||
|
||||
if (on)
|
||||
fptr->on = on;
|
||||
if (fade)
|
||||
fptr->on = fade;
|
||||
else
|
||||
fptr->on = 1;
|
||||
|
||||
|
@ -232,19 +379,7 @@ void AddFire(int x, int y, int z, char size, short roomNum, short on)
|
|||
fptr->y = y;
|
||||
fptr->z = z;
|
||||
fptr->roomNumber = roomNum;
|
||||
|
||||
switch (size)
|
||||
{
|
||||
case SP_NORMALFIRE:
|
||||
fptr->size = 1;
|
||||
break;
|
||||
case SP_SMALLFIRE:
|
||||
fptr->size = 2;
|
||||
break;
|
||||
case SP_BIGFIRE:
|
||||
fptr->size = 3;
|
||||
break;
|
||||
}
|
||||
fptr->size = size;
|
||||
}
|
||||
|
||||
void ClearFires()
|
||||
|
@ -255,7 +390,7 @@ void ClearFires()
|
|||
|
||||
void UpdateFireSparks()
|
||||
{
|
||||
keep_those_fires_burning();
|
||||
UpdateFireProgress();
|
||||
|
||||
for (int i = 0; i < MAX_SPARKS_FIRE; i++)
|
||||
{
|
||||
|
@ -503,7 +638,7 @@ void TriggerGunSmoke(int x, int y, int z, short xv, short yv, short zv, byte ini
|
|||
spark->dShade = 64;
|
||||
}
|
||||
|
||||
spark->transType = TransTypeEnum::COLADD;
|
||||
spark->blendMode = BLEND_MODES::BLENDMODE_ADDITIVE;
|
||||
spark->x = x + (GetRandomControl() & 31) - 16;
|
||||
spark->y = y + (GetRandomControl() & 31) - 16;
|
||||
spark->z = z + (GetRandomControl() & 31) - 16;
|
||||
|
@ -586,7 +721,7 @@ void TriggerShatterSmoke(int x, int y, int z)
|
|||
spark->colFadeSpeed = 4;
|
||||
spark->dShade = (GetRandomControl() & 0x1F) + 64;
|
||||
spark->fadeToBlack = 24 - (GetRandomControl() & 7);
|
||||
spark->transType = TransTypeEnum::COLADD;
|
||||
spark->blendMode = BLEND_MODES::BLENDMODE_ADDITIVE;
|
||||
spark->life = spark->sLife = (GetRandomControl() & 7) + 48;
|
||||
spark->x = (GetRandomControl() & 0x1F) + x - 16;
|
||||
spark->y = (GetRandomControl() & 0x1F) + y - 16;
|
||||
|
@ -959,7 +1094,7 @@ void UpdateGunShells()
|
|||
int ceiling = GetCeiling(floor, gs->pos.Position.x, gs->pos.Position.y, gs->pos.Position.z);
|
||||
if (gs->pos.Position.y < ceiling)
|
||||
{
|
||||
SoundEffect(SFX_TR4_LARA_SHOTGUN_SHELL, &gs->pos);
|
||||
SoundEffect(SFX_TR4_SHOTGUN_SHELL, &gs->pos);
|
||||
gs->speed -= 4;
|
||||
|
||||
if (gs->speed < 8)
|
||||
|
@ -975,7 +1110,7 @@ void UpdateGunShells()
|
|||
int height = GetFloorHeight(floor, gs->pos.Position.x, gs->pos.Position.y, gs->pos.Position.z);
|
||||
if (gs->pos.Position.y >= height)
|
||||
{
|
||||
SoundEffect(SFX_TR4_LARA_SHOTGUN_SHELL, &gs->pos);
|
||||
SoundEffect(SFX_TR4_SHOTGUN_SHELL, &gs->pos);
|
||||
gs->speed -= 8;
|
||||
if (gs->speed >= 8)
|
||||
{
|
||||
|
@ -1004,7 +1139,7 @@ void AddWaterSparks(int x, int y, int z, int num)
|
|||
{
|
||||
for (int i = 0; i < num; i++)
|
||||
{
|
||||
SPARKS* spark = &Sparks[GetFreeSpark()];
|
||||
auto* spark = GetFreeParticle();
|
||||
|
||||
spark->on = 1;
|
||||
spark->sR = 127;
|
||||
|
@ -1020,7 +1155,7 @@ void AddWaterSparks(int x, int y, int z, int num)
|
|||
spark->sSize = 8;
|
||||
spark->dSize = 32;
|
||||
spark->scalar = 1;
|
||||
spark->transType = TransTypeEnum::COLADD;
|
||||
spark->blendMode = BLEND_MODES::BLENDMODE_ADDITIVE;
|
||||
int random = GetRandomControl() & 0xFFF;
|
||||
spark->xVel = -phd_sin(random << 4) * 128;
|
||||
spark->yVel = -GenerateInt(128, 256);
|
||||
|
@ -1203,7 +1338,7 @@ void TriggerLaraDrips(ItemInfo* item)
|
|||
}
|
||||
}
|
||||
|
||||
int ExplodingDeath(short itemNumber, int meshBits, short flags)
|
||||
int ExplodingDeath(short itemNumber, unsigned int meshBits, short flags)
|
||||
{
|
||||
ItemInfo* item = &g_Level.Items[itemNumber];
|
||||
ObjectInfo* obj = &Objects[item->ObjectNumber];
|
||||
|
@ -1319,7 +1454,7 @@ int ExplodingDeath(short itemNumber, int meshBits, short flags)
|
|||
}
|
||||
}
|
||||
|
||||
return item->MeshBits == 0;
|
||||
return item->MeshBits == NO_JOINT_BITS;
|
||||
}
|
||||
|
||||
int GetFreeShockwave()
|
||||
|
@ -1355,7 +1490,7 @@ void TriggerShockwave(PHD_3DPOS* pos, short innerRad, short outerRad, int speed,
|
|||
sptr->b = b;
|
||||
sptr->life = life;
|
||||
|
||||
SoundEffect(SFX_TR5_IMP_STONEHIT, pos);
|
||||
SoundEffect(SFX_TR5_IMP_STONE_HIT, pos);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1366,7 +1501,7 @@ void TriggerShockwaveHitEffect(int x, int y, int z, byte r, byte g, byte b, shor
|
|||
|
||||
if (dx >= -16384 && dx <= 16384 && dz >= -16384 && dz <= 16384)
|
||||
{
|
||||
SPARKS* spark = &Sparks[GetFreeSpark()];
|
||||
auto* spark = GetFreeParticle();
|
||||
spark->dB = b;
|
||||
spark->on = true;
|
||||
spark->sR = 0;
|
||||
|
@ -1376,7 +1511,7 @@ void TriggerShockwaveHitEffect(int x, int y, int z, byte r, byte g, byte b, shor
|
|||
spark->dR = r;
|
||||
spark->colFadeSpeed = 4;
|
||||
spark->fadeToBlack = 8;
|
||||
spark->transType = TransTypeEnum::COLADD;
|
||||
spark->blendMode = BLEND_MODES::BLENDMODE_ADDITIVE;
|
||||
spark->life = spark->sLife = (GetRandomControl() & 3) + 16;
|
||||
|
||||
int speed = (GetRandomControl() & 0xF) + vel;
|
||||
|
@ -1407,7 +1542,7 @@ void TriggerShockwaveHitEffect(int x, int y, int z, byte r, byte g, byte b, shor
|
|||
spark->rotAdd = (GetRandomControl() & 0xF) + 16;
|
||||
|
||||
spark->scalar = 1;
|
||||
spark->def = Objects[ID_DEFAULT_SPRITES].meshIndex + SPR_UNDERWATERDUST;
|
||||
spark->spriteIndex = Objects[ID_DEFAULT_SPRITES].meshIndex + SPR_UNDERWATERDUST;
|
||||
spark->maxYvel = 0;
|
||||
spark->gravity = (GetRandomControl() & 0x3F) + 64;
|
||||
spark->sSize = spark->size = (GetRandomControl() & 0x1F) + 32;
|
||||
|
@ -1472,7 +1607,7 @@ void TriggerExplosionBubble(int x, int y, int z, short roomNumber)
|
|||
|
||||
if (dx >= -16384 && dx <= 16384 && dz >= -16384 && dz <= 16384)
|
||||
{
|
||||
auto* spark = &Sparks[GetFreeSpark()];
|
||||
auto* spark = GetFreeParticle();
|
||||
|
||||
spark->sR = 128;
|
||||
spark->dR = 128;
|
||||
|
@ -1485,7 +1620,7 @@ void TriggerExplosionBubble(int x, int y, int z, short roomNumber)
|
|||
spark->sB = 0;
|
||||
spark->colFadeSpeed = 8;
|
||||
spark->fadeToBlack = 12;
|
||||
spark->transType = TransTypeEnum::COLADD;
|
||||
spark->blendMode = BLEND_MODES::BLENDMODE_ADDITIVE;
|
||||
spark->x = x;
|
||||
spark->y = y;
|
||||
spark->z = z;
|
||||
|
@ -1496,7 +1631,7 @@ void TriggerExplosionBubble(int x, int y, int z, short roomNumber)
|
|||
spark->flags = 2058;
|
||||
spark->scalar = 3;
|
||||
spark->gravity = 0;
|
||||
spark->def = Objects[ID_DEFAULT_SPRITES].meshIndex + 13;
|
||||
spark->spriteIndex = Objects[ID_DEFAULT_SPRITES].meshIndex + 13;
|
||||
spark->maxYvel = 0;
|
||||
int size = (GetRandomControl() & 7) + 63;
|
||||
spark->sSize = size >> 1;
|
||||
|
@ -1516,7 +1651,7 @@ void TriggerExplosionBubble(int x, int y, int z, short roomNumber)
|
|||
|
||||
/*void TriggerExplosionSmokeEnd(int x, int y, int z, int unk)
|
||||
{
|
||||
auto* spark = &Sparks[GetFreeSpark()];
|
||||
auto* spark = GetFreeParticle();
|
||||
|
||||
spark->on = 1;
|
||||
if (unk)
|
||||
|
@ -1543,9 +1678,9 @@ void TriggerExplosionBubble(int x, int y, int z, short roomNumber)
|
|||
spark->life = spark->sLife = (GetRandomControl() & 0x1F) + 96;
|
||||
|
||||
if (unk)
|
||||
spark->transType = TransTypeEnum::COLADD;
|
||||
spark->blendMode = BLEND_MODES::BLENDMODE_ADDITIVE;
|
||||
else
|
||||
spark->transType = 3;
|
||||
spark->blendMode = 3;
|
||||
|
||||
spark->x = (GetRandomControl() & 0x1F) + x - 16;
|
||||
spark->y = (GetRandomControl() & 0x1F) + y - 16;
|
||||
|
@ -1603,7 +1738,7 @@ void TriggerExplosionBubble(int x, int y, int z, short roomNumber)
|
|||
|
||||
void TriggerFenceSparks(int x, int y, int z, int kill, int crane)
|
||||
{
|
||||
auto* spark = &Sparks[GetFreeSpark()];
|
||||
auto* spark = GetFreeParticle();
|
||||
|
||||
spark->on = 1;
|
||||
spark->sR = (GetRandomControl() & 0x3F) - 0x40;
|
||||
|
@ -1618,7 +1753,7 @@ void TriggerFenceSparks(int x, int y, int z, int kill, int crane)
|
|||
|
||||
spark->life = (GetRandomControl() & 7) + 24;
|
||||
spark->sLife = (GetRandomControl() & 7) + 24;
|
||||
spark->transType = TransTypeEnum::COLADD;
|
||||
spark->blendMode = BLEND_MODES::BLENDMODE_ADDITIVE;
|
||||
spark->dynamic = -1;
|
||||
|
||||
spark->x = x;
|
||||
|
@ -1643,7 +1778,7 @@ void TriggerSmallSplash(int x, int y, int z, int number)
|
|||
{
|
||||
for (int i = 0; i < number; i++)
|
||||
{
|
||||
auto* sptr = &Sparks[GetFreeSpark()];
|
||||
auto* sptr = GetFreeParticle();
|
||||
|
||||
sptr->on = 1;
|
||||
|
||||
|
@ -1661,7 +1796,7 @@ void TriggerSmallSplash(int x, int y, int z, int number)
|
|||
sptr->life = 24;
|
||||
sptr->sLife = 24;
|
||||
|
||||
sptr->transType = TransTypeEnum::COLADD;
|
||||
sptr->blendMode = BLEND_MODES::BLENDMODE_ADDITIVE;
|
||||
|
||||
int angle = GetRandomControl() << 3;
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include "Game/effects/effects.h"
|
||||
#include "Game/Lara/lara_struct.h"
|
||||
#include "Specific/phd_global.h"
|
||||
#include "Renderer/Renderer11Enums.h"
|
||||
|
||||
enum class LaraWeaponType;
|
||||
struct ItemInfo;
|
||||
|
@ -33,7 +34,7 @@ struct SMOKE_SPARKS
|
|||
byte fadeToBlack;
|
||||
signed char sLife;
|
||||
signed char life;
|
||||
TransTypeEnum transType;
|
||||
BLEND_MODES blendMode;
|
||||
byte fxObj;
|
||||
byte nodeNumber;
|
||||
byte mirror;
|
||||
|
@ -96,7 +97,7 @@ struct FIRE_LIST
|
|||
int y;
|
||||
int z;
|
||||
byte on;
|
||||
byte size;
|
||||
float size;
|
||||
short roomNumber;
|
||||
};
|
||||
|
||||
|
@ -179,14 +180,17 @@ extern int NextBlood;
|
|||
extern int NextSpider;
|
||||
extern int NextGunShell;
|
||||
|
||||
#define MAX_SPARKS_FIRE 20
|
||||
#define MAX_FIRE_LIST 32
|
||||
#define MAX_SPARKS_SMOKE 32
|
||||
#define MAX_SPARKS_BLOOD 32
|
||||
#define MAX_GUNFLASH 4
|
||||
#define MAX_GUNSHELL 24
|
||||
#define MAX_DRIPS 32
|
||||
#define MAX_SHOCKWAVE 16
|
||||
constexpr auto MAX_SPARKS_FIRE = 20;
|
||||
constexpr auto MAX_FIRE_LIST = 32;
|
||||
constexpr auto MAX_SPARKS_SMOKE = 32;
|
||||
constexpr auto MAX_SPARKS_BLOOD = 32;
|
||||
constexpr auto MAX_GUNFLASH = 4;
|
||||
constexpr auto MAX_GUNSHELL = 24;
|
||||
constexpr auto MAX_DRIPS = 32;
|
||||
constexpr auto MAX_SHOCKWAVE = 16;
|
||||
|
||||
constexpr auto EXPLODE_HIT_EFFECT = 258;
|
||||
constexpr auto EXPLODE_NORMAL = 256;
|
||||
|
||||
extern GUNFLASH_STRUCT Gunflashes[MAX_GUNFLASH];
|
||||
extern FIRE_SPARKS FireSparks[MAX_SPARKS_FIRE];
|
||||
|
@ -196,7 +200,6 @@ extern BLOOD_STRUCT Blood[MAX_SPARKS_BLOOD];
|
|||
extern DRIP_STRUCT Drips[MAX_DRIPS];
|
||||
extern SHOCKWAVE_STRUCT ShockWaves[MAX_SHOCKWAVE];
|
||||
extern FIRE_LIST Fires[MAX_FIRE_LIST];
|
||||
extern SMOKE_SPARKS SmokeSparks[MAX_SPARKS_SMOKE];
|
||||
|
||||
void TriggerBlood(int x, int y, int z, int unk, int num);
|
||||
void TriggerExplosionBubble(int x, int y, int z, short roomNumber);
|
||||
|
@ -204,9 +207,12 @@ int GetFreeFireSpark();
|
|||
void TriggerGlobalStaticFlame();
|
||||
void TriggerGlobalFireSmoke();
|
||||
void TriggerGlobalFireFlame();
|
||||
void keep_those_fires_burning();
|
||||
void TriggerPilotFlame(int itemNum, int nodeIndex);
|
||||
void ThrowFire(int itemNum, int meshIndex, Vector3Int offset, Vector3Int speed);
|
||||
void ThrowPoison(int itemNum, int meshIndex, Vector3Int offset, Vector3Int speed, Vector3 color);
|
||||
void UpdateFireProgress();
|
||||
void ClearFires();
|
||||
void AddFire(int x, int y, int z, char size, short roomNum, short on);
|
||||
void AddFire(int x, int y, int z, short roomNum, float size, short fade);
|
||||
void UpdateFireSparks();
|
||||
int GetFreeSmokeSpark();
|
||||
void UpdateSmoke();
|
||||
|
@ -227,14 +233,9 @@ void UpdateBubbles();
|
|||
int GetFreeDrip();
|
||||
void UpdateDrips();
|
||||
void TriggerLaraDrips(ItemInfo* item);
|
||||
|
||||
constexpr auto EXPLODE_HIT_EFFECT = 258;
|
||||
constexpr auto EXPLODE_NORMAL = 256;
|
||||
int ExplodingDeath(short itemNumber, int meshBits, short flags); // EXPLODE_ flags
|
||||
|
||||
int ExplodingDeath(short itemNumber, unsigned int meshBits, short flags); // EXPLODE_ flags
|
||||
int GetFreeShockwave();
|
||||
void TriggerShockwave(PHD_3DPOS* pos, short innerRad, short outerRad, int speed, char r, char g, char b, char life, short angle, short flags);
|
||||
void TriggerShockwaveHitEffect(int x, int y, int z, int color, short rot, int vel);
|
||||
void TriggerShockwaveHitEffect(int x, int y, int z, byte r, byte g, byte b, short rot, int vel);
|
||||
void UpdateShockwaves();
|
||||
void TriggerSmallSplash(int x, int y, int z, int number);
|
||||
void SetFadeClip(short height, int velocity);
|
||||
|
|
|
@ -146,254 +146,254 @@ InventoryObject inventry_objects_list[INVENTORY_TABLE_SIZE] =
|
|||
{
|
||||
// Weapons
|
||||
|
||||
{ID_PISTOLS_ITEM, 6, 0.5f, ANGLE(90), ANGLE(243.69873046875f), ANGLE(276.1328125), OPT_EQUIP | OPT_COMBINABLE | OPT_CHOOSEAMMO_PISTOLS, STRING_PISTOLS, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PISTOLS_AMMO_ITEM, 4, 0.5f, 0, ANGLE(90), 0, OPT_USE, STRING_PISTOLS_AMMO, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_UZI_ITEM, -4, 0.5f, ANGLE(-90) , ANGLE(135), ANGLE(90), OPT_EQUIP | OPT_COMBINABLE | OPT_CHOOSEAMMO_UZI, STRING_UZI , NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_UZI_AMMO_ITEM, 5, 0.5f, 0, 5384, 0, OPT_USE, STRING_UZI_AMMO, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PISTOLS_ITEM, 6, 0.5f, ANGLE(90), ANGLE(243.69873046875f), ANGLE(276.1328125), OPT_EQUIP | OPT_COMBINABLE | OPT_CHOOSEAMMO_PISTOLS, STRING_PISTOLS, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PISTOLS_AMMO_ITEM, 4, 0.5f, 0, ANGLE(90), 0, OPT_USE, STRING_PISTOLS_AMMO, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_UZI_ITEM, -4, 0.5f, ANGLE(-90) , ANGLE(135), ANGLE(90), OPT_EQUIP | OPT_COMBINABLE | OPT_CHOOSEAMMO_UZI, STRING_UZI , NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_UZI_AMMO_ITEM, 5, 0.5f, 0, 5384, 0, OPT_USE, STRING_UZI_AMMO, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_SHOTGUN_ITEM, -6, 0.8f, ANGLE(-20), ANGLE(270), ANGLE(45), OPT_EQUIP | OPT_COMBINABLE | OPT_CHOOSEAMMO_SHOTGUN, STRING_SHOTGUN, 1, INV_ROT_Y},
|
||||
{ID_SHOTGUN_AMMO1_ITEM, 0, 0.5f, ANGLE(90), 0, 0, OPT_USE, STRING_SHOTGUN_AMMO1, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_SHOTGUN_AMMO2_ITEM, 0, 0.5f, ANGLE(90), 0, 0, OPT_USE, STRING_SHOTGUN_AMMO2, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_SHOTGUN_AMMO1_ITEM, 0, 0.5f, ANGLE(90), 0, 0, OPT_USE, STRING_SHOTGUN_AMMO1, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_SHOTGUN_AMMO2_ITEM, 0, 0.5f, ANGLE(90), 0, 0, OPT_USE, STRING_SHOTGUN_AMMO2, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_REVOLVER_ITEM, 0, 0.5f, ANGLE(-90), ANGLE(60), ANGLE(85), OPT_EQUIP | OPT_COMBINABLE | OPT_CHOOSEAMMO_REVOLVER, STRING_REVOLVER , 1, INV_ROT_Y},
|
||||
{ID_REVOLVER_AMMO_ITEM, 0, 0.5f, ANGLE(90), ANGLE(-16), 0, OPT_USE, STRING_REVOLVER_AMMO, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_REVOLVER_AMMO_ITEM, 0, 0.5f, ANGLE(90), ANGLE(-16), 0, OPT_USE, STRING_REVOLVER_AMMO, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_REVOLVER_ITEM, 0, 0.5f, ANGLE(90), ANGLE(60), ANGLE(85), OPT_EQUIP | OPT_SEPERATABLE | OPT_CHOOSEAMMO_REVOLVER, STRING_REVOLVER_LASER, 3, INV_ROT_Y},
|
||||
{ID_CROSSBOW_ITEM, 0, 0.5f, ANGLE(-90), ANGLE(33), 0, OPT_EQUIP | OPT_COMBINABLE | OPT_CHOOSEAMMO_CROSSBOW, STRING_CROSSBOW, 1, INV_ROT_Y},
|
||||
{ID_CROSSBOW_ITEM, 0, 0.5f, ANGLE(-90), ANGLE(33), 0, OPT_EQUIP | OPT_SEPERATABLE | OPT_CHOOSEAMMO_CROSSBOW, STRING_CROSSBOW_LASER, 3, INV_ROT_Y},
|
||||
{ID_CROSSBOW_AMMO1_ITEM, 0, 0.5f, ANGLE(90), 0, 0, OPT_USE, STRING_CROSSBOW_AMMO1, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_CROSSBOW_AMMO2_ITEM, 0, 0.5f, ANGLE(90), 0, 0, OPT_USE, STRING_CROSSBOW_AMMO1, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_CROSSBOW_AMMO3_ITEM, 0, 0.5f, ANGLE(90), 0, 0, OPT_USE, STRING_CROSSBOW_AMMO1, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_CROSSBOW_AMMO1_ITEM, 0, 0.5f, ANGLE(90), 0, 0, OPT_USE, STRING_CROSSBOW_AMMO1, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_CROSSBOW_AMMO2_ITEM, 0, 0.5f, ANGLE(90), 0, 0, OPT_USE, STRING_CROSSBOW_AMMO1, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_CROSSBOW_AMMO3_ITEM, 0, 0.5f, ANGLE(90), 0, 0, OPT_USE, STRING_CROSSBOW_AMMO1, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_HK_ITEM, 0, 0.5f, ANGLE(0), ANGLE(280), 0, OPT_EQUIP | OPT_COMBINABLE | OPT_CHOOSEAMMO_HK, STRING_HK, 1, INV_ROT_Y},
|
||||
{ID_HK_ITEM, 0, 0.5f, ANGLE(-45), ANGLE(280), 0, OPT_EQUIP | OPT_SEPERATABLE | OPT_CHOOSEAMMO_HK, STRING_HK_SILENCED, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_HK_ITEM, 0, 0.5f, ANGLE(-45), ANGLE(280), 0, OPT_EQUIP | OPT_SEPERATABLE | OPT_CHOOSEAMMO_HK, STRING_HK_SILENCED, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_HK_AMMO_ITEM, 3, 0.5f, ANGLE(90), 0, 0, OPT_USE, STRING_HK_AMMO, 2},
|
||||
{ID_GRENADE_GUN_ITEM, 0, 0.5f, ANGLE(90), 0, ANGLE(65), OPT_EQUIP | OPT_COMBINABLE | OPT_CHOOSEAMMO_GRENADEGUN, STRING_GRENADE_LAUNCHER, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_GRENADE_AMMO1_ITEM, 3, 0.5f, ANGLE(90), 0, 0, OPT_USE, STRING_GRENADE_AMMO1, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_GRENADE_AMMO2_ITEM, 3, 0.5f, ANGLE(90), 0, 0, OPT_USE, STRING_GRENADE_AMMO2, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_GRENADE_AMMO3_ITEM, 3, 0.5f, ANGLE(90), 0, 0, OPT_USE, STRING_GRENADE_AMMO3, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_HARPOON_ITEM, 0, 0.5f, 0, ANGLE(-65), ANGLE(-20), OPT_EQUIP | OPT_COMBINABLE | OPT_CHOOSEAMMO_HARPOON, STRING_HARPOON_GUN, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_HARPOON_AMMO_ITEM, 3, 0.5f, 0, ANGLE(15), 0, OPT_USE, STRING_HARPOON_AMMO, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_ROCKET_LAUNCHER_ITEM, 0, 0.5f, ANGLE(180), ANGLE(80), 0, OPT_EQUIP | OPT_COMBINABLE | OPT_CHOOSEAMMO_ROCKET, STRING_ROCKET_LAUNCHER, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_ROCKET_LAUNCHER_AMMO_ITEM, 3, 0.5f, ANGLE(90), 0, ANGLE(15), OPT_USE, STRING_ROCKET_AMMO, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_GRENADE_GUN_ITEM, 0, 0.5f, ANGLE(90), 0, ANGLE(65), OPT_EQUIP | OPT_COMBINABLE | OPT_CHOOSEAMMO_GRENADEGUN, STRING_GRENADE_LAUNCHER, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_GRENADE_AMMO1_ITEM, 3, 0.5f, ANGLE(90), 0, 0, OPT_USE, STRING_GRENADE_AMMO1, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_GRENADE_AMMO2_ITEM, 3, 0.5f, ANGLE(90), 0, 0, OPT_USE, STRING_GRENADE_AMMO2, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_GRENADE_AMMO3_ITEM, 3, 0.5f, ANGLE(90), 0, 0, OPT_USE, STRING_GRENADE_AMMO3, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_HARPOON_ITEM, 0, 0.5f, 0, ANGLE(-65), ANGLE(-20), OPT_EQUIP | OPT_COMBINABLE | OPT_CHOOSEAMMO_HARPOON, STRING_HARPOON_GUN, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_HARPOON_AMMO_ITEM, 3, 0.5f, 0, ANGLE(15), 0, OPT_USE, STRING_HARPOON_AMMO, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_ROCKET_LAUNCHER_ITEM, 0, 0.5f, ANGLE(180), ANGLE(80), 0, OPT_EQUIP | OPT_COMBINABLE | OPT_CHOOSEAMMO_ROCKET, STRING_ROCKET_LAUNCHER, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_ROCKET_LAUNCHER_AMMO_ITEM, 3, 0.5f, ANGLE(90), 0, ANGLE(15), OPT_USE, STRING_ROCKET_AMMO, NO_JOINT_BITS, INV_ROT_Y},
|
||||
|
||||
// Misc
|
||||
|
||||
{ID_LASERSIGHT_ITEM, 2, 0.5f, ANGLE(90), ANGLE(10), 0, OPT_USE | OPT_COMBINABLE, STRING_LASERSIGHT, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_SILENCER_ITEM, 1, 0.5f, 0, ANGLE(10), 0, OPT_USE | OPT_COMBINABLE, STRING_SILENCER, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_BIGMEDI_ITEM, 2, 0.7f, ANGLE(180), 0, 0, OPT_USE, STRING_LARGE_MEDIPACK, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_SMALLMEDI_ITEM, 0, 0.7f, ANGLE(180), ANGLE(112), 0, OPT_USE, STRING_SMALL_MEDIPACK, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_BINOCULARS_ITEM, -1, 0.5f, ANGLE(180), ANGLE(10), 0, OPT_USE, STRING_BINOCULARS, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_FLARE_INV_ITEM, 52, 0.8f, ANGLE(0), 0, 0, OPT_USE, STRING_FLARES, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_TIMEX_ITEM, 2, 0.4f, 0, 0, 0, OPT_STATS, STRING_TIMEX, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PC_LOAD_INV_ITEM, 52, 0.3f, ANGLE(180), 0, 0, OPT_LOAD, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PC_LOAD_SAVE_ITEM, 52, 0.3f, ANGLE(180), 0, 0, OPT_SAVE, STRING_SAVE_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_BURNING_TORCH_ITEM, 14, 0.5f, 0, ANGLE(90), 0, OPT_USE, STRING_TORCH, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_CROWBAR_ITEM, 4, 0.5f, 0, ANGLE(90), 0, OPT_USE, STRING_CROWBAR, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_DIARY_ITEM, 0, 0.3f, ANGLE(180), 0, 0, OPT_DIARY, STRING_DIARY, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_COMPASS_ITEM, -14, 0.5f, 0, 0, 0, 0, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_CLOCKWORK_BEETLE, 14, 0.5f, 0, 0, 0, OPT_USE, STRING_CLOCKWORK_BEETLE, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_CLOCKWORK_BEETLE_COMBO1, 18, 0.5f, 0, 0, 0, OPT_COMBINABLE, STRING_CLOCKWORK_BEETLE_COMBO1, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_CLOCKWORK_BEETLE_COMBO2, 14, 0.5f, 0, 0, 0, OPT_COMBINABLE, STRING_CLOCKWORK_BEETLE_COMBO2, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_WATERSKIN1_EMPTY, 2, 0.5f, 0, ANGLE(285), 0, OPT_USE | OPT_COMBINABLE, STRING_WATERSKIN_SMALL_EMPTY, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_WATERSKIN1_1, 2, 0.5f, 0, ANGLE(285), 0, OPT_USE | OPT_COMBINABLE, STRING_WATERSKIN_SMALL_1, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_WATERSKIN1_2, 2, 0.5f, 0, ANGLE(285), 0, OPT_USE | OPT_COMBINABLE, STRING_WATERSKIN_SMALL_2, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_WATERSKIN1_3, 2, 0.5f, 0, ANGLE(285), 0, OPT_USE | OPT_COMBINABLE, STRING_WATERSKIN_SMALL_3, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_WATERSKIN2_EMPTY, 2, 0.5f, 0, ANGLE(285), 0, OPT_USE | OPT_COMBINABLE, STRING_WATERSKIN_LARGE_EMPTY, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_WATERSKIN2_1, 2, 0.5f, 0, ANGLE(285), 0, OPT_USE | OPT_COMBINABLE, STRING_WATERSKIN_LARGE_1, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_WATERSKIN2_2, 2, 0.5f, 0, ANGLE(285), 0, OPT_USE | OPT_COMBINABLE, STRING_WATERSKIN_LARGE_2, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_WATERSKIN2_3, 2, 0.5f, 0, ANGLE(285), 0, OPT_USE | OPT_COMBINABLE, STRING_WATERSKIN_LARGE_3, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_WATERSKIN2_4, 2, 0.5f, 0, ANGLE(285), 0, OPT_USE | OPT_COMBINABLE, STRING_WATERSKIN_LARGE_4, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_WATERSKIN2_5, 2, 0.5f, 0, ANGLE(285), 0, OPT_USE | OPT_COMBINABLE, STRING_WATERSKIN_LARGE_5, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_LASERSIGHT_ITEM, 2, 0.5f, ANGLE(90), ANGLE(10), 0, OPT_USE | OPT_COMBINABLE, STRING_LASERSIGHT, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_SILENCER_ITEM, 1, 0.5f, 0, ANGLE(10), 0, OPT_USE | OPT_COMBINABLE, STRING_SILENCER, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_BIGMEDI_ITEM, 2, 0.7f, ANGLE(180), 0, 0, OPT_USE, STRING_LARGE_MEDIPACK, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_SMALLMEDI_ITEM, 0, 0.7f, ANGLE(180), ANGLE(112), 0, OPT_USE, STRING_SMALL_MEDIPACK, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_BINOCULARS_ITEM, -1, 0.5f, ANGLE(180), ANGLE(10), 0, OPT_USE, STRING_BINOCULARS, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_FLARE_INV_ITEM, 52, 0.8f, ANGLE(0), 0, 0, OPT_USE, STRING_FLARES, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_TIMEX_ITEM, 2, 0.4f, 0, 0, 0, OPT_STATS, STRING_TIMEX, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PC_LOAD_INV_ITEM, 52, 0.3f, ANGLE(180), 0, 0, OPT_LOAD, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PC_LOAD_SAVE_ITEM, 52, 0.3f, ANGLE(180), 0, 0, OPT_SAVE, STRING_SAVE_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_BURNING_TORCH_ITEM, 14, 0.5f, 0, ANGLE(90), 0, OPT_USE, STRING_TORCH, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_CROWBAR_ITEM, 4, 0.5f, 0, ANGLE(90), 0, OPT_USE, STRING_CROWBAR, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_DIARY_ITEM, 0, 0.3f, ANGLE(180), 0, 0, OPT_DIARY, STRING_DIARY, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_COMPASS_ITEM, -14, 0.5f, 0, 0, 0, 0, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_CLOCKWORK_BEETLE, 14, 0.5f, 0, 0, 0, OPT_USE, STRING_CLOCKWORK_BEETLE, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_CLOCKWORK_BEETLE_COMBO1, 18, 0.5f, 0, 0, 0, OPT_COMBINABLE, STRING_CLOCKWORK_BEETLE_COMBO1, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_CLOCKWORK_BEETLE_COMBO2, 14, 0.5f, 0, 0, 0, OPT_COMBINABLE, STRING_CLOCKWORK_BEETLE_COMBO2, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_WATERSKIN1_EMPTY, 2, 0.5f, 0, ANGLE(285), 0, OPT_USE | OPT_COMBINABLE, STRING_WATERSKIN_SMALL_EMPTY, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_WATERSKIN1_1, 2, 0.5f, 0, ANGLE(285), 0, OPT_USE | OPT_COMBINABLE, STRING_WATERSKIN_SMALL_1, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_WATERSKIN1_2, 2, 0.5f, 0, ANGLE(285), 0, OPT_USE | OPT_COMBINABLE, STRING_WATERSKIN_SMALL_2, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_WATERSKIN1_3, 2, 0.5f, 0, ANGLE(285), 0, OPT_USE | OPT_COMBINABLE, STRING_WATERSKIN_SMALL_3, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_WATERSKIN2_EMPTY, 2, 0.5f, 0, ANGLE(285), 0, OPT_USE | OPT_COMBINABLE, STRING_WATERSKIN_LARGE_EMPTY, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_WATERSKIN2_1, 2, 0.5f, 0, ANGLE(285), 0, OPT_USE | OPT_COMBINABLE, STRING_WATERSKIN_LARGE_1, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_WATERSKIN2_2, 2, 0.5f, 0, ANGLE(285), 0, OPT_USE | OPT_COMBINABLE, STRING_WATERSKIN_LARGE_2, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_WATERSKIN2_3, 2, 0.5f, 0, ANGLE(285), 0, OPT_USE | OPT_COMBINABLE, STRING_WATERSKIN_LARGE_3, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_WATERSKIN2_4, 2, 0.5f, 0, ANGLE(285), 0, OPT_USE | OPT_COMBINABLE, STRING_WATERSKIN_LARGE_4, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_WATERSKIN2_5, 2, 0.5f, 0, ANGLE(285), 0, OPT_USE | OPT_COMBINABLE, STRING_WATERSKIN_LARGE_5, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_OPEN_DIARY_ITEM, 0, 0.9f, ANGLE(90), 0, 0, 0, 0, 0, 0},
|
||||
|
||||
// Puzzles
|
||||
|
||||
{ID_PUZZLE_ITEM1, 14, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM2, 14, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM3, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM4, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM5, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM6, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM7, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM8, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM9, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM10, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM11, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM12, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM13, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM14, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM15, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM16, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM1, 14, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM2, 14, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM3, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM4, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM5, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM6, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM7, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM8, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM9, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM10, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM11, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM12, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM13, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM14, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM15, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM16, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
|
||||
// Puzzle combos
|
||||
|
||||
{ID_PUZZLE_ITEM1_COMBO1, 18, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM1_COMBO2, 18, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM2_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM2_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM3_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM3_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM4_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM4_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM5_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM5_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM6_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM6_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM7_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM7_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM8_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM8_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM9_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM9_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM10_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM10_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM11_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM11_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM12_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM12_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM13_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM13_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM14_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM14_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM15_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM15_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM16_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM16_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM1_COMBO1, 18, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM1_COMBO2, 18, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM2_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM2_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM3_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM3_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM4_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM4_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM5_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM5_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM6_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM6_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM7_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM7_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM8_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM8_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM9_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM9_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM10_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM10_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM11_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM11_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM12_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM12_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM13_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM13_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM14_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM14_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM15_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM15_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM16_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PUZZLE_ITEM16_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
|
||||
// Keys
|
||||
|
||||
{ID_KEY_ITEM1, 14, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM2, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM3, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM4, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM5, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM6, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM7, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM8, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM9, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM10, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM11, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM12, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM13, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM14, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM15, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM16, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM1, 14, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM2, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM3, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM4, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM5, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM6, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM7, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM8, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM9, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM10, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM11, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM12, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM13, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM14, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM15, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM16, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
|
||||
// Key combos
|
||||
|
||||
{ID_KEY_ITEM1_COMBO1, 18, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM1_COMBO2, 18, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM2_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM2_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM3_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM3_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM4_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM4_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM5_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM5_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM6_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM6_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM7_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM7_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM8_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM8_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM9_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM9_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM10_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM10_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM11_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM11_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM12_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM12_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM13_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM13_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM14_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM14_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM15_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM15_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM16_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM16_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM1_COMBO1, 18, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM1_COMBO2, 18, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM2_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM2_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM3_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM3_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM4_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM4_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM5_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM5_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM6_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM6_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM7_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM7_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM8_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM8_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM9_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM9_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM10_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM10_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM11_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM11_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM12_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM12_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM13_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM13_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM14_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM14_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM15_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM15_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM16_COMBO1, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_KEY_ITEM16_COMBO2, 8, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
|
||||
// Pickups
|
||||
|
||||
{ID_PICKUP_ITEM1, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM2, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM3, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM4, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM5, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM6, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM7, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM8, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM9, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM10, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM11, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM12, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM13, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM14, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM15, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM16, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM1, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM2, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM3, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM4, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM5, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM6, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM7, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM8, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM9, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM10, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM11, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM12, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM13, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM14, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM15, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM16, 8, 0.5f, 0, 0, 0, OPT_USE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
|
||||
// Pickup combos
|
||||
|
||||
{ID_PICKUP_ITEM1_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM1_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM2_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM2_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM3_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM3_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM4_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM4_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM5_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM5_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM6_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM6_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM7_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM7_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM8_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM8_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM9_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM9_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM10_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM10_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM11_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM11_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM12_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM12_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM13_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM13_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM14_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM14_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM15_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM15_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM16_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM16_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM1_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM1_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM2_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM2_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM3_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM3_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM4_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM4_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM5_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM5_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM6_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM6_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM7_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM7_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM8_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM8_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM9_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM9_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM10_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM10_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM11_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM11_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM12_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM12_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM13_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM13_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM14_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM14_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM15_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM15_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM16_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_PICKUP_ITEM16_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
|
||||
// Examines
|
||||
|
||||
{ID_EXAMINE1, 4, 0.5f, 0, 0, 0, OPT_EXAMINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_EXAMINE2, 14, 0.5f, 0, 0, 0, OPT_EXAMINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_EXAMINE3, 14, 0.5f, 0, 0, 0, OPT_EXAMINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_EXAMINE4, 14, 0.5f, 0, 0, 0, OPT_EXAMINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_EXAMINE5, 14, 0.5f, 0, 0, 0, OPT_EXAMINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_EXAMINE6, 14, 0.5f, 0, 0, 0, OPT_EXAMINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_EXAMINE7, 14, 0.5f, 0, 0, 0, OPT_EXAMINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_EXAMINE8, 14, 0.5f, 0, 0, 0, OPT_EXAMINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_EXAMINE1, 4, 0.5f, 0, 0, 0, OPT_EXAMINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_EXAMINE2, 14, 0.5f, 0, 0, 0, OPT_EXAMINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_EXAMINE3, 14, 0.5f, 0, 0, 0, OPT_EXAMINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_EXAMINE4, 14, 0.5f, 0, 0, 0, OPT_EXAMINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_EXAMINE5, 14, 0.5f, 0, 0, 0, OPT_EXAMINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_EXAMINE6, 14, 0.5f, 0, 0, 0, OPT_EXAMINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_EXAMINE7, 14, 0.5f, 0, 0, 0, OPT_EXAMINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_EXAMINE8, 14, 0.5f, 0, 0, 0, OPT_EXAMINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
|
||||
// Examines combos
|
||||
|
||||
{ID_EXAMINE1_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_EXAMINE1_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_EXAMINE2_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_EXAMINE2_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_EXAMINE3_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_EXAMINE3_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_EXAMINE4_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_EXAMINE4_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_EXAMINE5_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_EXAMINE5_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_EXAMINE6_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_EXAMINE6_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_EXAMINE7_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_EXAMINE7_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_EXAMINE8_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_EXAMINE8_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_MESH_BITS, INV_ROT_Y},
|
||||
{ID_EXAMINE1_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_EXAMINE1_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_EXAMINE2_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_EXAMINE2_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_EXAMINE3_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_EXAMINE3_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_EXAMINE4_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_EXAMINE4_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_EXAMINE5_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_EXAMINE5_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_EXAMINE6_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_EXAMINE6_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_EXAMINE7_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_EXAMINE7_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_EXAMINE8_COMBO1, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
{ID_EXAMINE8_COMBO2, 14, 0.5f, 0, 0, 0, OPT_USE | OPT_COMBINABLE, STRING_LOAD_GAME, NO_JOINT_BITS, INV_ROT_Y},
|
||||
};
|
||||
|
||||
SettingsData GuiController::GetCurrentSettings()
|
||||
|
@ -626,15 +626,27 @@ InventoryResult GuiController::TitleOptions()
|
|||
|
||||
DoDebouncedInput();
|
||||
|
||||
if (menu_to_display == Menu::Title || menu_to_display == Menu::SelectLevel ||
|
||||
menu_to_display == Menu::LoadGame || menu_to_display == Menu::Options)
|
||||
if (menu_to_display == Menu::LoadGame)
|
||||
{
|
||||
DoLoad();
|
||||
|
||||
if (invMode == InventoryMode::InGame)
|
||||
{
|
||||
menu_to_display = Menu::Title;
|
||||
selected_option = selected_option_bak;
|
||||
}
|
||||
}
|
||||
else if (menu_to_display == Menu::Title ||
|
||||
menu_to_display == Menu::SelectLevel ||
|
||||
menu_to_display == Menu::Options)
|
||||
{
|
||||
if (goUp)
|
||||
{
|
||||
if (selected_option <= 0)
|
||||
selected_option += option_count;
|
||||
|
||||
if (menu_to_display == Menu::LoadGame)
|
||||
selected_save_slot = (selected_save_slot <= 0) ? option_count : selected_option - 1;
|
||||
else
|
||||
selected_option--;
|
||||
selected_option = (selected_option <= 0) ? option_count : selected_option - 1;
|
||||
|
||||
SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always);
|
||||
}
|
||||
|
@ -705,13 +717,12 @@ InventoryResult GuiController::TitleOptions()
|
|||
}
|
||||
else if (menu_to_display == Menu::LoadGame)
|
||||
{
|
||||
if (!SavegameInfos[selected_option].Present)
|
||||
if (!SavegameInfos[selected_save_slot].Present)
|
||||
SayNo();
|
||||
else
|
||||
{
|
||||
SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always);
|
||||
g_GameFlow->SelectedSaveGame = selected_option;
|
||||
selected_option = 0;
|
||||
g_GameFlow->SelectedSaveGame = selected_save_slot;
|
||||
ret = InventoryResult::LoadGame;
|
||||
}
|
||||
}
|
||||
|
@ -1250,8 +1261,10 @@ InventoryResult GuiController::DoPauseMenu()
|
|||
|
||||
if (goSelect)
|
||||
{
|
||||
if (menu_to_display == Menu::Pause)
|
||||
switch (menu_to_display)
|
||||
{
|
||||
case Menu::Pause:
|
||||
|
||||
switch (selected_option)
|
||||
{
|
||||
case 0:
|
||||
|
@ -1268,9 +1281,10 @@ InventoryResult GuiController::DoPauseMenu()
|
|||
invMode = InventoryMode::None;
|
||||
return InventoryResult::ExitToTitle;
|
||||
}
|
||||
}
|
||||
else if (menu_to_display == Menu::Options)
|
||||
{
|
||||
break;
|
||||
|
||||
case Menu::Options:
|
||||
|
||||
switch (selected_option)
|
||||
{
|
||||
case 0:
|
||||
|
@ -1289,6 +1303,12 @@ InventoryResult GuiController::DoPauseMenu()
|
|||
menu_to_display = Menu::Sound;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case Menu::Statistics:
|
||||
menu_to_display = Menu::Pause;
|
||||
SoundEffect(SFX_TR4_MENU_SELECT, nullptr, SoundEnvironment::Always);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1996,7 +2016,7 @@ void GuiController::UseCurrentItem()
|
|||
OldBinocular = BinocularRange;
|
||||
Lara.Inventory.OldBusy = false;
|
||||
BinocularRange = 0;
|
||||
LaraItem->MeshBits = -1;
|
||||
LaraItem->MeshBits = ALL_JOINT_BITS;
|
||||
invobject = rings[(int)RingTypes::Inventory]->current_object_list[rings[(int)RingTypes::Inventory]->curobjinlist].invitem;
|
||||
gmeobject = inventry_objects_list[invobject].object_number;
|
||||
|
||||
|
@ -2250,7 +2270,7 @@ void GuiController::UseCurrentItem()
|
|||
}
|
||||
}
|
||||
|
||||
void GuiController::HandleInventoryMenu()
|
||||
void GuiController::DoInventory()
|
||||
{
|
||||
int n;
|
||||
unsigned __int64 opts;
|
||||
|
@ -2260,7 +2280,7 @@ void GuiController::HandleInventoryMenu()
|
|||
|
||||
if (rings[(int)RingTypes::Ammo]->ringactive)
|
||||
{
|
||||
g_Renderer.DrawString(phd_centerx, phd_centery, g_GameFlow->GetString(optmessages[5]), PRINTSTRING_COLOR_WHITE, PRINTSTRING_BLINK | PRINTSTRING_CENTER);
|
||||
g_Renderer.DrawString(phd_centerx, phd_centery, g_GameFlow->GetString(optmessages[5]), PRINTSTRING_COLOR_WHITE, PRINTSTRING_BLINK | PRINTSTRING_CENTER | PRINTSTRING_OUTLINE);
|
||||
|
||||
if (rings[(int)RingTypes::Inventory]->objlistmovement)
|
||||
return;
|
||||
|
@ -2452,12 +2472,12 @@ void GuiController::HandleInventoryMenu()
|
|||
{
|
||||
if (i == current_selected_option)
|
||||
{
|
||||
g_Renderer.DrawString(phd_centerx, ypos, current_options[i].text, PRINTSTRING_COLOR_WHITE, PRINTSTRING_BLINK | PRINTSTRING_CENTER);
|
||||
g_Renderer.DrawString(phd_centerx, ypos, current_options[i].text, PRINTSTRING_COLOR_WHITE, PRINTSTRING_BLINK | PRINTSTRING_CENTER | PRINTSTRING_OUTLINE);
|
||||
ypos += font_height;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_Renderer.DrawString(phd_centerx, ypos, current_options[i].text, PRINTSTRING_COLOR_WHITE, PRINTSTRING_CENTER);
|
||||
g_Renderer.DrawString(phd_centerx, ypos, current_options[i].text, PRINTSTRING_COLOR_WHITE, PRINTSTRING_CENTER | PRINTSTRING_OUTLINE);
|
||||
ypos += font_height;
|
||||
}
|
||||
}
|
||||
|
@ -2710,7 +2730,7 @@ void GuiController::DrawAmmoSelector()
|
|||
yrot = ammo_object_list[n].yrot;
|
||||
zrot = ammo_object_list[n].zrot;
|
||||
x = phd_centerx - 300 + xpos;
|
||||
y = 430;
|
||||
y = 480;
|
||||
short obj = ConvertInventoryItemToObject(ammo_object_list[n].invitem);
|
||||
float scaler = inventry_objects_list[ammo_object_list[n].invitem].scale1;
|
||||
|
||||
|
@ -2722,7 +2742,7 @@ void GuiController::DrawAmmoSelector()
|
|||
sprintf(&invTextBuffer[0], "%d x %s", ammo_object_list[n].amount, g_GameFlow->GetString(inventry_objects_list[ammo_object_list[n].invitem].objname));
|
||||
|
||||
if (ammo_selector_fade_val)
|
||||
g_Renderer.DrawString(phd_centerx, 380, &invTextBuffer[0], PRINTSTRING_COLOR_YELLOW, PRINTSTRING_CENTER);
|
||||
g_Renderer.DrawString(phd_centerx, 380, &invTextBuffer[0], PRINTSTRING_COLOR_YELLOW, PRINTSTRING_CENTER | PRINTSTRING_OUTLINE);
|
||||
|
||||
|
||||
if (n == *current_ammo_type)
|
||||
|
@ -3028,7 +3048,7 @@ void GuiController::DrawCurrentObjectList(int ringnum)
|
|||
else
|
||||
objmeup = (int)((phd_winymax + 1) * 0.0625 * 3.0 + phd_centery);
|
||||
|
||||
g_Renderer.DrawString(phd_centerx, ringnum == (int)RingTypes::Inventory ? 230 : 300, textbufme, PRINTSTRING_COLOR_YELLOW, PRINTSTRING_CENTER);
|
||||
g_Renderer.DrawString(phd_centerx, ringnum == (int)RingTypes::Inventory ? 230 : 300, textbufme, PRINTSTRING_COLOR_YELLOW, PRINTSTRING_CENTER | PRINTSTRING_OUTLINE);
|
||||
}
|
||||
|
||||
if (!i && !rings[ringnum]->objlistmovement)
|
||||
|
@ -3083,7 +3103,7 @@ void GuiController::DrawCurrentObjectList(int ringnum)
|
|||
int x, y, y2;
|
||||
x = 400 + xoff + i * OBJLIST_SPACING;
|
||||
y = 150;
|
||||
y2 = 430;//combine
|
||||
y2 = 480;//combine
|
||||
short obj = ConvertInventoryItemToObject(rings[ringnum]->current_object_list[n].invitem);
|
||||
float scaler = inventry_objects_list[rings[ringnum]->current_object_list[n].invitem].scale1;
|
||||
g_Renderer.DrawObjectOn2DPosition(x, ringnum == (int)RingTypes::Inventory ? y : y2, obj, xrot, yrot, zrot, scaler);
|
||||
|
@ -3204,25 +3224,36 @@ int GuiController::CallInventory(bool reset_mode)
|
|||
return return_value;
|
||||
|
||||
DoDebouncedInput();
|
||||
|
||||
if (invMode == InventoryMode::Statistics)
|
||||
DoStatisticsMode();
|
||||
|
||||
if (invMode == InventoryMode::Examine)
|
||||
DoExamineMode();
|
||||
|
||||
if (invMode == InventoryMode::Diary)
|
||||
DoDiary();
|
||||
|
||||
if (invMode == InventoryMode::Load)
|
||||
return_value = DoLoad();
|
||||
|
||||
if (invMode == InventoryMode::Save)
|
||||
DoSave();
|
||||
|
||||
DrawInventory();
|
||||
DrawCompass();
|
||||
|
||||
switch (invMode)
|
||||
{
|
||||
case InventoryMode::InGame:
|
||||
DoInventory();
|
||||
break;
|
||||
|
||||
case InventoryMode::Statistics:
|
||||
DoStatisticsMode();
|
||||
break;
|
||||
|
||||
case InventoryMode::Examine:
|
||||
DoExamineMode();
|
||||
break;
|
||||
|
||||
case InventoryMode::Diary:
|
||||
DoDiary();
|
||||
break;
|
||||
|
||||
case InventoryMode::Load:
|
||||
return_value = DoLoad();
|
||||
break;
|
||||
|
||||
case InventoryMode::Save:
|
||||
DoSave();
|
||||
break;
|
||||
}
|
||||
|
||||
if (useItem && !TrInput)
|
||||
val = 1;
|
||||
|
||||
|
@ -3310,7 +3341,7 @@ void GuiController::DoDiary()
|
|||
|
||||
short GuiController::GetLoadSaveSelection()
|
||||
{
|
||||
return selected_slot;
|
||||
return selected_save_slot;
|
||||
}
|
||||
|
||||
int GuiController::DoLoad()
|
||||
|
@ -3321,30 +3352,30 @@ int GuiController::DoLoad()
|
|||
{
|
||||
SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always);
|
||||
|
||||
if (selected_slot == SAVEGAME_MAX - 1)
|
||||
selected_slot -= SAVEGAME_MAX - 1; //go back up
|
||||
if (selected_save_slot == SAVEGAME_MAX - 1)
|
||||
selected_save_slot -= SAVEGAME_MAX - 1; //go back up
|
||||
else
|
||||
selected_slot++;
|
||||
selected_save_slot++;
|
||||
}
|
||||
|
||||
if (goUp)
|
||||
{
|
||||
SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always);
|
||||
|
||||
if (selected_slot== 0)
|
||||
selected_slot += SAVEGAME_MAX - 1; //go back down
|
||||
if (selected_save_slot== 0)
|
||||
selected_save_slot += SAVEGAME_MAX - 1; //go back down
|
||||
else
|
||||
selected_slot--;
|
||||
selected_save_slot--;
|
||||
}
|
||||
|
||||
if (goSelect)
|
||||
{
|
||||
if (!SavegameInfos[selected_slot].Present)
|
||||
if (!SavegameInfos[selected_save_slot].Present)
|
||||
SayNo();
|
||||
else
|
||||
{
|
||||
SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always);
|
||||
g_GameFlow->SelectedSaveGame = selected_slot;
|
||||
g_GameFlow->SelectedSaveGame = selected_save_slot;
|
||||
ExitInvLoop = 1;
|
||||
return 1;
|
||||
}
|
||||
|
@ -3368,26 +3399,26 @@ void GuiController::DoSave()
|
|||
{
|
||||
SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always);
|
||||
|
||||
if (selected_slot == SAVEGAME_MAX - 1)
|
||||
selected_slot -= SAVEGAME_MAX - 1; //go back up
|
||||
if (selected_save_slot == SAVEGAME_MAX - 1)
|
||||
selected_save_slot -= SAVEGAME_MAX - 1; //go back up
|
||||
else
|
||||
selected_slot++;
|
||||
selected_save_slot++;
|
||||
}
|
||||
|
||||
if (goUp)
|
||||
{
|
||||
SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always);
|
||||
|
||||
if (selected_slot == 0)
|
||||
selected_slot += SAVEGAME_MAX - 1; //go back down
|
||||
if (selected_save_slot == 0)
|
||||
selected_save_slot += SAVEGAME_MAX - 1; //go back down
|
||||
else
|
||||
selected_slot--;
|
||||
selected_save_slot--;
|
||||
}
|
||||
|
||||
if (goSelect)
|
||||
{
|
||||
SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always);
|
||||
SaveGame::Save(selected_slot);
|
||||
SaveGame::Save(selected_save_slot);
|
||||
ExitInvLoop = 1; //exit inv if the user has saved
|
||||
}
|
||||
|
||||
|
|
|
@ -392,7 +392,7 @@ struct InventoryObject
|
|||
short zrot;
|
||||
unsigned __int64 opts;
|
||||
const char* objname;
|
||||
unsigned long meshbits;
|
||||
unsigned int meshbits;
|
||||
short rot_flags;
|
||||
};
|
||||
|
||||
|
@ -402,7 +402,6 @@ public:
|
|||
int CallInventory(bool reset_mode);
|
||||
InventoryResult TitleOptions();
|
||||
InventoryResult DoPauseMenu();
|
||||
void HandleInventoryMenu();
|
||||
void DrawInventory();
|
||||
void DrawCurrentObjectList(int ringnum);
|
||||
int IsObjectInInventory(short object_number);
|
||||
|
@ -460,9 +459,11 @@ private:
|
|||
void DoDiary();
|
||||
int DoLoad();
|
||||
void DoSave();
|
||||
void DoInventory();
|
||||
void ConstructCombineObjectList();
|
||||
|
||||
/*vars*/
|
||||
|
||||
// Input
|
||||
bool goUp, goDown, goRight, goLeft, goSelect, goDeselect;
|
||||
bool dbUp, dbDown, dbRight, dbLeft, dbSelect, dbDeselect;
|
||||
|
@ -536,14 +537,13 @@ private:
|
|||
char StashedCurrentHarpoonAmmoType;
|
||||
char StashedCurrentRocketAmmoType;
|
||||
|
||||
// GUI vars
|
||||
Menu menu_to_display = Menu::Title;
|
||||
short selected_option;
|
||||
int selected_option;
|
||||
int option_count;
|
||||
int selected_save_slot;
|
||||
|
||||
SettingsData CurrentSettings;
|
||||
|
||||
// Load / save
|
||||
short selected_slot;
|
||||
};
|
||||
|
||||
/*inventory*/
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "Specific/level.h"
|
||||
|
||||
using namespace TEN::Renderer;
|
||||
|
||||
short PickupX;
|
||||
short PickupY;
|
||||
short CurrentPickup;
|
||||
|
@ -31,6 +32,18 @@ extern RendererHUDBar* g_AirBar;
|
|||
|
||||
bool EnableSmoothHealthBar = true;
|
||||
|
||||
void DrawHUD(ItemInfo* item)
|
||||
{
|
||||
if (CurrentLevel == 0 || CinematicBarsHeight > 0)
|
||||
return;
|
||||
|
||||
int flash = FlashIt();
|
||||
UpdateSprintBar(LaraItem);
|
||||
UpdateHealthBar(LaraItem, flash);
|
||||
UpdateAirBar(LaraItem, flash);
|
||||
DrawAllPickups();
|
||||
}
|
||||
|
||||
void DrawHealthBarOverlay(ItemInfo* item, int value)
|
||||
{
|
||||
auto* lara = GetLaraInfo(item);
|
||||
|
@ -43,7 +56,7 @@ void DrawHealthBarOverlay(ItemInfo* item, int value)
|
|||
else
|
||||
color2 = 0xA00000;
|
||||
|
||||
g_Renderer.DrawBar(value, ::g_HealthBar, ID_HEALTH_BAR_TEXTURE, GlobalCounter, Lara.PoisonPotency);
|
||||
g_Renderer.DrawBar(value, g_HealthBar, ID_HEALTH_BAR_TEXTURE, GlobalCounter, Lara.PoisonPotency);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -52,7 +65,7 @@ void DrawHealthBar(ItemInfo* item, float value)
|
|||
auto* lara = GetLaraInfo(item);
|
||||
|
||||
if (CurrentLevel)
|
||||
g_Renderer.DrawBar(value, ::g_HealthBar, ID_HEALTH_BAR_TEXTURE, GlobalCounter, Lara.PoisonPotency);
|
||||
g_Renderer.DrawBar(value, g_HealthBar, ID_HEALTH_BAR_TEXTURE, GlobalCounter, Lara.PoisonPotency);
|
||||
}
|
||||
|
||||
void UpdateHealthBar(ItemInfo* item, int flash)
|
||||
|
@ -141,7 +154,7 @@ void UpdateHealthBar(ItemInfo* item, int flash)
|
|||
void DrawAirBar(float value)
|
||||
{
|
||||
if (CurrentLevel)
|
||||
g_Renderer.DrawBar(value, ::g_AirBar,ID_AIR_BAR_TEXTURE,0,0);
|
||||
g_Renderer.DrawBar(value, g_AirBar,ID_AIR_BAR_TEXTURE,0,0);
|
||||
}
|
||||
|
||||
void UpdateAirBar(ItemInfo* item, int flash)
|
||||
|
@ -180,7 +193,7 @@ void UpdateAirBar(ItemInfo* item, int flash)
|
|||
void DrawSprintBar(float value)
|
||||
{
|
||||
if (CurrentLevel)
|
||||
g_Renderer.DrawBar(value, ::g_DashBar, ID_DASH_BAR_TEXTURE, 0, 0);
|
||||
g_Renderer.DrawBar(value, g_DashBar, ID_DASH_BAR_TEXTURE, 0, 0);
|
||||
}
|
||||
|
||||
void UpdateSprintBar(ItemInfo* item)
|
||||
|
@ -236,7 +249,7 @@ void DrawAllPickups()
|
|||
}
|
||||
}
|
||||
|
||||
g_Renderer.drawPickup(Pickups[CurrentPickup].ObjectNumber);
|
||||
g_Renderer.DrawPickup(Pickups[CurrentPickup].ObjectNumber);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ struct DisplayPickup
|
|||
short ObjectNumber;
|
||||
};
|
||||
|
||||
void DrawHUD(ItemInfo* item);
|
||||
void DrawHealthBarOverlay(ItemInfo* item, int value);
|
||||
void DrawHealthBar(ItemInfo* item, float value);
|
||||
void UpdateHealthBar(ItemInfo* item, int flash);
|
||||
|
|
|
@ -12,6 +12,98 @@
|
|||
|
||||
using namespace TEN::Floordata;
|
||||
|
||||
void ItemInfo::SetBits(JointBitType type, std::vector<int> jointIndices)
|
||||
{
|
||||
for (int i = 0; i < jointIndices.size(); i++)
|
||||
{
|
||||
unsigned int jointBit = (unsigned int)(1 << jointIndices[i]);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case JointBitType::Touch:
|
||||
this->TouchBits |= jointBit;
|
||||
break;
|
||||
|
||||
case JointBitType::Mesh:
|
||||
this->MeshBits |= jointBit;
|
||||
break;
|
||||
|
||||
case JointBitType::MeshSwap:
|
||||
this->MeshSwapBits |= jointBit;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ItemInfo::SetBits(JointBitType type, int jointIndex)
|
||||
{
|
||||
return SetBits(type, std::vector { jointIndex });
|
||||
}
|
||||
|
||||
void ItemInfo::ClearBits(JointBitType type, std::vector<int> jointIndices)
|
||||
{
|
||||
for (int i = 0; i < jointIndices.size(); i++)
|
||||
{
|
||||
unsigned int jointBit = (unsigned int)(1 << jointIndices[i]);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case JointBitType::Touch:
|
||||
this->TouchBits &= ~jointBit;
|
||||
break;
|
||||
|
||||
case JointBitType::Mesh:
|
||||
this->MeshBits &= ~jointBit;
|
||||
break;
|
||||
|
||||
case JointBitType::MeshSwap:
|
||||
this->MeshSwapBits &= ~jointBit;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ItemInfo::ClearBits(JointBitType type, int jointIndex)
|
||||
{
|
||||
return ClearBits(type, std::vector { jointIndex });
|
||||
}
|
||||
|
||||
bool ItemInfo::TestBits(JointBitType type, std::vector<int> jointIndices)
|
||||
{
|
||||
for (int i = 0; i < jointIndices.size(); i++)
|
||||
{
|
||||
unsigned int jointBit = (unsigned int)(1 << jointIndices[i]);
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case JointBitType::Touch:
|
||||
if ((TouchBits & jointBit) == jointBit)
|
||||
return true;
|
||||
|
||||
break;
|
||||
|
||||
case JointBitType::Mesh:
|
||||
if ((MeshBits & jointBit) == jointBit)
|
||||
return true;
|
||||
|
||||
break;
|
||||
|
||||
case JointBitType::MeshSwap:
|
||||
if ((MeshSwapBits & jointBit) == jointBit)
|
||||
return true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ItemInfo::TestBits(JointBitType type, int jointIndex)
|
||||
{
|
||||
return TestBits(type, std::vector { jointIndex });
|
||||
}
|
||||
|
||||
void ClearItem(short itemNumber)
|
||||
{
|
||||
auto* item = &g_Level.Items[itemNumber];
|
||||
|
@ -76,13 +168,10 @@ void KillItem(short const itemNumber)
|
|||
if (Objects[item->ObjectNumber].floor != nullptr)
|
||||
UpdateBridgeItem(itemNumber, true);
|
||||
|
||||
|
||||
g_GameScriptEntities->NotifyKilled(item);
|
||||
g_GameScriptEntities->TryRemoveColliding(itemNumber, true);
|
||||
if (!item->LuaCallbackOnKilledName.empty())
|
||||
{
|
||||
g_GameScript->ExecuteFunction(item->LuaCallbackOnKilledName, itemNumber);
|
||||
}
|
||||
|
||||
item->LuaName.clear();
|
||||
item->LuaCallbackOnKilledName.clear();
|
||||
|
@ -96,11 +185,8 @@ void KillItem(short const itemNumber)
|
|||
NextItemFree = itemNumber;
|
||||
}
|
||||
else
|
||||
{
|
||||
item->Flags |= IFLAG_KILLED;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void RemoveAllItemsInRoom(short roomNumber, short objectNumber)
|
||||
|
@ -383,11 +469,11 @@ void InitialiseItem(short itemNumber)
|
|||
item->MeshBits = 1;
|
||||
}
|
||||
else
|
||||
item->MeshBits = -1;
|
||||
item->MeshBits = ALL_JOINT_BITS;
|
||||
|
||||
item->TouchBits = 0;
|
||||
item->TouchBits = NO_JOINT_BITS;
|
||||
item->AfterDeath = 0;
|
||||
item->SwapMeshFlags = 0;
|
||||
item->MeshSwapBits = NO_JOINT_BITS;
|
||||
|
||||
if (item->Flags & IFLAG_INVISIBLE)
|
||||
{
|
||||
|
|
|
@ -16,10 +16,7 @@ enum GAME_OBJECT_ID : short;
|
|||
#define GRAY555 RGB555(128, 128, 128)
|
||||
#define BLACK555 RGB555( 0, 0, 0)
|
||||
|
||||
constexpr unsigned int NO_MESH_BITS = UINT_MAX;
|
||||
|
||||
constexpr auto NO_ITEM = -1;
|
||||
constexpr auto ALL_MESHBITS = -1;
|
||||
constexpr auto NOT_TARGETABLE = -16384;
|
||||
constexpr auto NUM_ITEMS = 1024;
|
||||
|
||||
|
@ -52,6 +49,16 @@ enum ItemFlags
|
|||
IFLAG_ACTIVATION_MASK = 0x3E00 // bits 9-13
|
||||
};
|
||||
|
||||
constexpr unsigned int ALL_JOINT_BITS = UINT_MAX;
|
||||
constexpr unsigned int NO_JOINT_BITS = 0;
|
||||
|
||||
enum class JointBitType
|
||||
{
|
||||
Touch,
|
||||
Mesh,
|
||||
MeshSwap
|
||||
};
|
||||
|
||||
struct EntityAnimationData
|
||||
{
|
||||
int AnimNumber;
|
||||
|
@ -94,13 +101,13 @@ struct ItemInfo
|
|||
int Timer;
|
||||
short Shade;
|
||||
|
||||
uint32_t TouchBits;
|
||||
uint32_t MeshBits;
|
||||
unsigned int TouchBits;
|
||||
unsigned int MeshBits;
|
||||
unsigned int MeshSwapBits;
|
||||
|
||||
uint16_t Flags; // ItemFlags enum
|
||||
unsigned short Flags; // ItemFlags enum
|
||||
short ItemFlags[8];
|
||||
short TriggerFlags;
|
||||
uint32_t SwapMeshFlags;
|
||||
|
||||
// TODO: Move to CreatureInfo?
|
||||
uint8_t AIBits; // AIObjectType enum.
|
||||
|
@ -113,6 +120,13 @@ struct ItemInfo
|
|||
std::string LuaCallbackOnHitName;
|
||||
std::string LuaCallbackOnCollidedWithObjectName;
|
||||
std::string LuaCallbackOnCollidedWithRoomName;
|
||||
|
||||
void SetBits(JointBitType type, std::vector<int> jointIndices);
|
||||
void SetBits(JointBitType type, int jointIndex);
|
||||
void ClearBits(JointBitType type, std::vector<int> jointIndices);
|
||||
void ClearBits(JointBitType type, int jointIndex);
|
||||
bool TestBits(JointBitType type, std::vector<int> jointIndices);
|
||||
bool TestBits(JointBitType type, int jointIndex);
|
||||
};
|
||||
|
||||
void EffectNewRoom(short fxNumber, short roomNumber);
|
||||
|
|
|
@ -67,7 +67,7 @@ void ControlMissile(short fxNumber)
|
|||
// fx->frameNumber = -GetRandomControl()/11000;
|
||||
// fx->counter = 6;
|
||||
// fx->objectNumber = RICOCHET1;
|
||||
SoundEffect((fx->objectNumber == ID_SCUBA_HARPOON) ? SFX_TR4_LARA_RICOCHET : SFX_TR2_CIRCLE_BLADE_HIT, &fx->pos);
|
||||
SoundEffect((fx->objectNumber == ID_SCUBA_HARPOON) ? SFX_TR4_WEAPON_RICOCHET : SFX_TR2_CIRCLE_BLADE_HIT, &fx->pos);
|
||||
}
|
||||
/*else if (fx->objectNumber == DRAGON_FIRE)
|
||||
{
|
||||
|
|
|
@ -40,24 +40,25 @@ namespace TEN::Effects
|
|||
p.size = GenerateFloat(256, 512);
|
||||
}
|
||||
|
||||
void TriggerSpeedboatFoam(ItemInfo* boat)
|
||||
void TriggerSpeedboatFoam(ItemInfo* boat, Vector3 offset)
|
||||
{
|
||||
for (float i = -0.5; i < 1; i += 1)
|
||||
{
|
||||
float size = GenerateFloat(96, 128);
|
||||
float angle = TO_RAD(boat->Pose.Orientation.y);
|
||||
float angleVariation = i*2*10 * RADIAN;
|
||||
float y = float(boat->Pose.Position.y) - size / 2 + offset.y;
|
||||
float x = std::sin(angle + angleVariation);
|
||||
float z = std::cos(angle + angleVariation);
|
||||
x = x * -700 + boat->Pose.Position.x;
|
||||
z = z * -700 + boat->Pose.Position.z;
|
||||
x = x * offset.z + z * offset.x + boat->Pose.Position.x;
|
||||
z = z * offset.z + x * offset.x + boat->Pose.Position.z;
|
||||
SimpleParticle& p = getFreeSimpleParticle();
|
||||
p = {};
|
||||
p.active = true;
|
||||
p.life = GenerateFloat(5, 9);
|
||||
p.room = boat->RoomNumber;
|
||||
p.ageRate = GenerateFloat(0.9, 1.3);
|
||||
float size = GenerateFloat(96, 128);
|
||||
p.worldPosition = { x, float(boat->Pose.Position.y) - size / 2, z };
|
||||
p.worldPosition = { x, y, z };
|
||||
p.sequence = ID_MOTOR_BOAT_FOAM_SPRITES;
|
||||
p.size = GenerateFloat(256, 512);
|
||||
}
|
||||
|
|
|
@ -22,6 +22,6 @@ namespace TEN::Effects{
|
|||
|
||||
SimpleParticle& getFreeSimpleParticle();
|
||||
void TriggerSnowmobileSnow(ItemInfo* snowMobile);
|
||||
void TriggerSpeedboatFoam(ItemInfo* boat);
|
||||
void TriggerSpeedboatFoam(ItemInfo* boat, Vector3 offset);
|
||||
void updateSimpleParticles();
|
||||
}
|
|
@ -204,9 +204,7 @@ void DoPickup(ItemInfo* laraItem)
|
|||
short pickupItemNumber = getThisItemPlease;
|
||||
auto* pickupItem = &g_Level.Items[pickupItemNumber];
|
||||
|
||||
short oldXrot = pickupItem->Pose.Orientation.x;
|
||||
short oldYrot = pickupItem->Pose.Orientation.y;
|
||||
short oldZrot = pickupItem->Pose.Orientation.z;
|
||||
auto oldOrient = pickupItem->Pose.Orientation;
|
||||
|
||||
if (pickupItem->ObjectNumber == ID_BURNING_TORCH_ITEM)
|
||||
{
|
||||
|
@ -215,9 +213,7 @@ void DoPickup(ItemInfo* laraItem)
|
|||
lara->Torch.IsLit = (pickupItem->ItemFlags[3] & 1);
|
||||
|
||||
KillItem(pickupItemNumber);
|
||||
pickupItem->Pose.Orientation.x = oldXrot;
|
||||
pickupItem->Pose.Orientation.y = oldYrot;
|
||||
pickupItem->Pose.Orientation.z = oldZrot;
|
||||
pickupItem->Pose.Orientation = oldOrient;
|
||||
getThisItemPlease = NO_ITEM;
|
||||
return;
|
||||
}
|
||||
|
@ -233,9 +229,7 @@ void DoPickup(ItemInfo* laraItem)
|
|||
DrawFlareMeshes(laraItem);
|
||||
KillItem(pickupItemNumber);
|
||||
|
||||
pickupItem->Pose.Orientation.x = oldXrot;
|
||||
pickupItem->Pose.Orientation.y = oldYrot;
|
||||
pickupItem->Pose.Orientation.z = oldZrot;
|
||||
pickupItem->Pose.Orientation = oldOrient;
|
||||
getThisItemPlease = NO_ITEM;
|
||||
return;
|
||||
}
|
||||
|
@ -265,9 +259,7 @@ void DoPickup(ItemInfo* laraItem)
|
|||
pickupItem->Status = ITEM_INVISIBLE;
|
||||
}
|
||||
|
||||
pickupItem->Pose.Orientation.x = oldXrot;
|
||||
pickupItem->Pose.Orientation.y = oldYrot;
|
||||
pickupItem->Pose.Orientation.z = oldZrot;
|
||||
pickupItem->Pose.Orientation = oldOrient;
|
||||
getThisItemPlease = NO_ITEM;
|
||||
return;
|
||||
}
|
||||
|
@ -298,9 +290,7 @@ void DoPickup(ItemInfo* laraItem)
|
|||
pickupItem->Status = ITEM_INVISIBLE;
|
||||
}
|
||||
|
||||
pickupItem->Pose.Orientation.x = oldXrot;
|
||||
pickupItem->Pose.Orientation.y = oldYrot;
|
||||
pickupItem->Pose.Orientation.z = oldZrot;
|
||||
pickupItem->Pose.Orientation = oldOrient;
|
||||
KillItem(pickupItemNumber);
|
||||
getThisItemPlease = NO_ITEM;
|
||||
return;
|
||||
|
@ -315,9 +305,7 @@ void PickupCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll)
|
|||
{
|
||||
auto* item = &g_Level.Items[itemNumber];
|
||||
|
||||
short oldXrot = item->Pose.Orientation.x;
|
||||
short oldYrot = item->Pose.Orientation.y;
|
||||
short oldZrot = item->Pose.Orientation.z;
|
||||
auto oldOrient = item->Pose.Orientation;
|
||||
|
||||
if (item->Status == ITEM_INVISIBLE)
|
||||
return;
|
||||
|
@ -386,16 +374,12 @@ void PickupCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll)
|
|||
}
|
||||
}
|
||||
|
||||
item->Pose.Orientation.x = oldXrot;
|
||||
item->Pose.Orientation.y = oldYrot;
|
||||
item->Pose.Orientation.z = oldZrot;
|
||||
item->Pose.Orientation = oldOrient;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
item->Pose.Orientation.x = oldXrot;
|
||||
item->Pose.Orientation.y = oldYrot;
|
||||
item->Pose.Orientation.z = oldZrot;
|
||||
item->Pose.Orientation = oldOrient;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -412,16 +396,12 @@ void PickupCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll)
|
|||
{
|
||||
if (laraItem->Animation.ActiveState != LS_PICKUP && laraItem->Animation.ActiveState != LS_HOLE)
|
||||
{
|
||||
item->Pose.Orientation.x = oldXrot;
|
||||
item->Pose.Orientation.y = oldYrot;
|
||||
item->Pose.Orientation.z = oldZrot;
|
||||
item->Pose.Orientation = oldOrient;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
item->Pose.Orientation.x = oldXrot;
|
||||
item->Pose.Orientation.y = oldYrot;
|
||||
item->Pose.Orientation.z = oldZrot;
|
||||
item->Pose.Orientation = oldOrient;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -429,9 +409,7 @@ void PickupCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll)
|
|||
|
||||
if (lara->InteractedItem != itemNumber)
|
||||
{
|
||||
item->Pose.Orientation.x = oldXrot;
|
||||
item->Pose.Orientation.y = oldYrot;
|
||||
item->Pose.Orientation.z = oldZrot;
|
||||
item->Pose.Orientation = oldOrient;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -453,9 +431,7 @@ void PickupCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll)
|
|||
}
|
||||
}
|
||||
|
||||
item->Pose.Orientation.x = oldXrot;
|
||||
item->Pose.Orientation.y = oldYrot;
|
||||
item->Pose.Orientation.z = oldZrot;
|
||||
item->Pose.Orientation = oldOrient;
|
||||
return;
|
||||
}
|
||||
else if (MoveLaraPosition(&HiddenPickUpPosition, item, laraItem))
|
||||
|
@ -470,14 +446,12 @@ void PickupCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll)
|
|||
break;
|
||||
|
||||
case 2: // Pickup with crowbar
|
||||
item->Pose.Orientation.y = oldYrot;
|
||||
item->Pose.Orientation.y = oldOrient.y;
|
||||
if (lara->Control.IsLow || !TestLaraPosition(&CrowbarPickUpBounds, item, laraItem))
|
||||
{
|
||||
if (!lara->Control.IsMoving)
|
||||
{
|
||||
item->Pose.Orientation.x = oldXrot;
|
||||
item->Pose.Orientation.y = oldYrot;
|
||||
item->Pose.Orientation.z = oldZrot;
|
||||
item->Pose.Orientation = oldOrient;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -487,9 +461,7 @@ void PickupCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll)
|
|||
Lara.Control.HandStatus = HandStatus::Free;
|
||||
}
|
||||
|
||||
item->Pose.Orientation.x = oldXrot;
|
||||
item->Pose.Orientation.y = oldYrot;
|
||||
item->Pose.Orientation.z = oldZrot;
|
||||
item->Pose.Orientation = oldOrient;
|
||||
return;
|
||||
}
|
||||
if (!lara->Control.IsMoving)
|
||||
|
@ -499,17 +471,13 @@ void PickupCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll)
|
|||
if (g_Gui.IsObjectInInventory(ID_CROWBAR_ITEM))
|
||||
g_Gui.SetEnterInventory(ID_CROWBAR_ITEM);
|
||||
|
||||
item->Pose.Orientation.x = oldXrot;
|
||||
item->Pose.Orientation.y = oldYrot;
|
||||
item->Pose.Orientation.z = oldZrot;
|
||||
item->Pose.Orientation = oldOrient;
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_Gui.GetInventoryItemChosen() != ID_CROWBAR_ITEM)
|
||||
{
|
||||
item->Pose.Orientation.x = oldXrot;
|
||||
item->Pose.Orientation.y = oldYrot;
|
||||
item->Pose.Orientation.z = oldZrot;
|
||||
item->Pose.Orientation = oldOrient;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -537,9 +505,7 @@ void PickupCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll)
|
|||
|
||||
if (!plinth)
|
||||
{
|
||||
item->Pose.Orientation.x = oldXrot;
|
||||
item->Pose.Orientation.y = oldYrot;
|
||||
item->Pose.Orientation.z = oldZrot;
|
||||
item->Pose.Orientation = oldOrient;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -579,9 +545,7 @@ void PickupCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll)
|
|||
|
||||
if (!lara->Control.IsMoving)
|
||||
{
|
||||
item->Pose.Orientation.x = oldXrot;
|
||||
item->Pose.Orientation.y = oldYrot;
|
||||
item->Pose.Orientation.z = oldZrot;
|
||||
item->Pose.Orientation = oldOrient;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -591,19 +555,15 @@ void PickupCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll)
|
|||
Lara.Control.HandStatus = HandStatus::Free;
|
||||
}
|
||||
|
||||
item->Pose.Orientation.x = oldXrot;
|
||||
item->Pose.Orientation.y = oldYrot;
|
||||
item->Pose.Orientation.z = oldZrot;
|
||||
item->Pose.Orientation = oldOrient;
|
||||
return;
|
||||
|
||||
case 9: // Pickup object and conver it to crowbar (like submarine level)
|
||||
item->Pose.Orientation.y = oldYrot;
|
||||
item->Pose.Orientation.y = oldOrient.y;
|
||||
|
||||
if (!TestLaraPosition(&JobyCrowPickUpBounds, item, laraItem))
|
||||
{
|
||||
item->Pose.Orientation.x = oldXrot;
|
||||
item->Pose.Orientation.y = oldYrot;
|
||||
item->Pose.Orientation.z = oldZrot;
|
||||
item->Pose.Orientation = oldOrient;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -625,9 +585,7 @@ void PickupCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll)
|
|||
{
|
||||
if (!lara->Control.IsMoving)
|
||||
{
|
||||
item->Pose.Orientation.x = oldXrot;
|
||||
item->Pose.Orientation.y = oldYrot;
|
||||
item->Pose.Orientation.z = oldZrot;
|
||||
item->Pose.Orientation = oldOrient;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -637,9 +595,7 @@ void PickupCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll)
|
|||
Lara.Control.HandStatus = HandStatus::Free;
|
||||
}
|
||||
|
||||
item->Pose.Orientation.x = oldXrot;
|
||||
item->Pose.Orientation.y = oldYrot;
|
||||
item->Pose.Orientation.z = oldZrot;
|
||||
item->Pose.Orientation = oldOrient;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -726,9 +682,7 @@ void PickupCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll)
|
|||
lara->Control.HandStatus = HandStatus::Busy;
|
||||
}
|
||||
|
||||
item->Pose.Orientation.x = oldXrot;
|
||||
item->Pose.Orientation.y = oldYrot;
|
||||
item->Pose.Orientation.z = oldZrot;
|
||||
item->Pose.Orientation = oldOrient;
|
||||
}
|
||||
|
||||
void RegeneratePickups()
|
||||
|
@ -740,32 +694,60 @@ void RegeneratePickups()
|
|||
if (item->Status == ITEM_INVISIBLE)
|
||||
{
|
||||
short ammo = 0;
|
||||
if (item->ObjectNumber == ID_CROSSBOW_AMMO1_ITEM)
|
||||
switch (item->ObjectNumber)
|
||||
{
|
||||
case ID_CROSSBOW_AMMO1_ITEM:
|
||||
ammo = Lara.Weapons[(int)LaraWeaponType::Crossbow].Ammo[(int)WeaponAmmoType::Ammo1];
|
||||
else if (item->ObjectNumber == ID_CROSSBOW_AMMO2_ITEM)
|
||||
break;
|
||||
|
||||
case ID_CROSSBOW_AMMO2_ITEM:
|
||||
ammo = Lara.Weapons[(int)LaraWeaponType::Crossbow].Ammo[(int)WeaponAmmoType::Ammo2];
|
||||
else if (item->ObjectNumber == ID_CROSSBOW_AMMO3_ITEM)
|
||||
break;
|
||||
|
||||
case ID_CROSSBOW_AMMO3_ITEM:
|
||||
ammo = Lara.Weapons[(int)LaraWeaponType::Crossbow].Ammo[(int)WeaponAmmoType::Ammo3];
|
||||
else if(item->ObjectNumber == ID_GRENADE_AMMO1_ITEM)
|
||||
break;
|
||||
|
||||
case ID_GRENADE_AMMO1_ITEM:
|
||||
ammo = Lara.Weapons[(int)LaraWeaponType::GrenadeLauncher].Ammo[(int)WeaponAmmoType::Ammo1];
|
||||
else if (item->ObjectNumber == ID_GRENADE_AMMO2_ITEM)
|
||||
break;
|
||||
|
||||
case ID_GRENADE_AMMO2_ITEM:
|
||||
ammo = Lara.Weapons[(int)LaraWeaponType::GrenadeLauncher].Ammo[(int)WeaponAmmoType::Ammo2];
|
||||
else if (item->ObjectNumber == ID_GRENADE_AMMO3_ITEM)
|
||||
break;
|
||||
|
||||
case ID_GRENADE_AMMO3_ITEM:
|
||||
ammo = Lara.Weapons[(int)LaraWeaponType::GrenadeLauncher].Ammo[(int)WeaponAmmoType::Ammo3];
|
||||
else if (item->ObjectNumber == ID_HK_AMMO_ITEM)
|
||||
break;
|
||||
|
||||
case ID_HK_AMMO_ITEM:
|
||||
ammo = Lara.Weapons[(int)LaraWeaponType::HK].Ammo[(int)WeaponAmmoType::Ammo1];
|
||||
else if (item->ObjectNumber == ID_UZI_AMMO_ITEM)
|
||||
break;
|
||||
|
||||
case ID_UZI_AMMO_ITEM:
|
||||
ammo = Lara.Weapons[(int)LaraWeaponType::Uzi].Ammo[(int)WeaponAmmoType::Ammo1];
|
||||
else if (item->ObjectNumber == ID_HARPOON_AMMO_ITEM)
|
||||
break;
|
||||
|
||||
case ID_HARPOON_AMMO_ITEM:
|
||||
ammo = Lara.Weapons[(int)LaraWeaponType::HarpoonGun].Ammo[(int)WeaponAmmoType::Ammo1];
|
||||
else if (item->ObjectNumber == ID_ROCKET_LAUNCHER_AMMO_ITEM)
|
||||
break;
|
||||
|
||||
case ID_ROCKET_LAUNCHER_AMMO_ITEM:
|
||||
ammo = Lara.Weapons[(int)LaraWeaponType::RocketLauncher].Ammo[(int)WeaponAmmoType::Ammo1];
|
||||
else if (item->ObjectNumber == ID_REVOLVER_AMMO_ITEM)
|
||||
break;
|
||||
|
||||
case ID_REVOLVER_AMMO_ITEM:
|
||||
ammo = Lara.Weapons[(int)LaraWeaponType::Revolver].Ammo[(int)WeaponAmmoType::Ammo1];
|
||||
else if (item->ObjectNumber == ID_SHOTGUN_AMMO1_ITEM)
|
||||
break;
|
||||
|
||||
case ID_SHOTGUN_AMMO1_ITEM:
|
||||
ammo = Lara.Weapons[(int)LaraWeaponType::Shotgun].Ammo[(int)WeaponAmmoType::Ammo1];
|
||||
else if (item->ObjectNumber == ID_SHOTGUN_AMMO1_ITEM)
|
||||
break;
|
||||
|
||||
case ID_SHOTGUN_AMMO2_ITEM:
|
||||
ammo = Lara.Weapons[(int)LaraWeaponType::Shotgun].Ammo[(int)WeaponAmmoType::Ammo2];
|
||||
break;
|
||||
}
|
||||
|
||||
if (ammo == 0)
|
||||
item->Status = ITEM_NOT_ACTIVE;
|
||||
|
@ -909,7 +891,7 @@ void InitialiseSearchObject(short itemNumber)
|
|||
auto* item = &g_Level.Items[itemNumber];
|
||||
if (item->ObjectNumber == ID_SEARCH_OBJECT1)
|
||||
{
|
||||
item->SwapMeshFlags = -1;
|
||||
item->MeshSwapBits = ALL_JOINT_BITS;
|
||||
item->MeshBits = 7;
|
||||
}
|
||||
else if (item->ObjectNumber == ID_SEARCH_OBJECT2)
|
||||
|
@ -932,9 +914,7 @@ void InitialiseSearchObject(short itemNumber)
|
|||
}
|
||||
}
|
||||
else if (Objects[item2->ObjectNumber].isPickup &&
|
||||
item->Pose.Position.x == item2->Pose.Position.x &&
|
||||
item->Pose.Position.y == item2->Pose.Position.y &&
|
||||
item->Pose.Position.z == item2->Pose.Position.z)
|
||||
item->Pose.Position == item2->Pose.Position)
|
||||
{
|
||||
item->ItemFlags[1] = itemNumber2;
|
||||
break;
|
||||
|
@ -981,10 +961,10 @@ void SearchObjectCollision(short itemNumber, ItemInfo* laraitem, CollisionInfo*
|
|||
{
|
||||
if (MoveLaraPosition(&SOPos, item, laraitem))
|
||||
{
|
||||
laraitem->Animation.ActiveState = LS_MISC_CONTROL;
|
||||
ResetLaraFlex(laraitem);
|
||||
laraitem->Animation.AnimNumber = SearchAnims[objectNumber];
|
||||
laraitem->Animation.FrameNumber = g_Level.Anims[laraitem->Animation.AnimNumber].frameBase;
|
||||
ResetLaraFlex(laraitem);
|
||||
laraitem->Animation.ActiveState = LS_MISC_CONTROL;
|
||||
Lara.Control.IsMoving = false;
|
||||
Lara.Control.HandStatus = HandStatus::Busy;
|
||||
|
||||
|
@ -1028,12 +1008,12 @@ void SearchObjectControl(short itemNumber)
|
|||
{
|
||||
if (frameNumber > 0)
|
||||
{
|
||||
item->SwapMeshFlags = 0;
|
||||
item->MeshBits = -1;
|
||||
item->MeshSwapBits = NO_JOINT_BITS;
|
||||
item->MeshBits = ALL_JOINT_BITS;
|
||||
}
|
||||
else
|
||||
{
|
||||
item->SwapMeshFlags = -1;
|
||||
item->MeshSwapBits = ALL_JOINT_BITS;
|
||||
item->MeshBits = 7;
|
||||
}
|
||||
}
|
||||
|
@ -1129,7 +1109,7 @@ bool UseSpecialItem(ItemInfo* item)
|
|||
|
||||
if (flag == 1)
|
||||
{
|
||||
if (use != ID_WATERSKIN1_3 && use != ID_WATERSKIN2_5 && (LaraItem->Pose.Position.y > Lara.WaterSurfaceDist))
|
||||
if (use != ID_WATERSKIN1_3 && use != ID_WATERSKIN2_5 && (Lara.WaterSurfaceDist < -SHALLOW_WATER_START_LEVEL))
|
||||
{
|
||||
if (use < ID_WATERSKIN1_3)
|
||||
Lara.Inventory.SmallWaterskin = 4;
|
||||
|
@ -1165,8 +1145,8 @@ bool UseSpecialItem(ItemInfo* item)
|
|||
item->Animation.AnimNumber = LA_WATERSKIN_POUR_LOW;
|
||||
|
||||
item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase;
|
||||
item->Animation.TargetState = LS_MISC_CONTROL;
|
||||
item->Animation.ActiveState = LS_MISC_CONTROL;
|
||||
item->Animation.TargetState = LS_MISC_CONTROL;
|
||||
Lara.Control.HandStatus = HandStatus::Busy;
|
||||
|
||||
g_Gui.SetInventoryItemChosen(NO_ITEM);
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "Game/control/flipeffect.h"
|
||||
#include "Game/control/lot.h"
|
||||
#include "Game/effects/lara_fx.h"
|
||||
#include "Game/effects/effects.h"
|
||||
#include "Game/items.h"
|
||||
#include "Game/itemdata/creature_info.h"
|
||||
#include "Game/Lara/lara.h"
|
||||
|
@ -90,10 +91,10 @@ bool SaveGame::Save(int slot)
|
|||
|
||||
Save::SaveGameHeaderBuilder sghb{ fbb };
|
||||
sghb.add_level_name(levelNameOffset);
|
||||
sghb.add_days((GameTimer / 30) / 8640);
|
||||
sghb.add_hours(((GameTimer / 30) % 86400) / 3600);
|
||||
sghb.add_minutes(((GameTimer / 30) / 60) % 6);
|
||||
sghb.add_seconds((GameTimer / 30) % 60);
|
||||
sghb.add_days((GameTimer / FPS) / 8640);
|
||||
sghb.add_hours(((GameTimer / FPS) % 86400) / 3600);
|
||||
sghb.add_minutes(((GameTimer / FPS) / 60) % 6);
|
||||
sghb.add_seconds((GameTimer / FPS) % 60);
|
||||
sghb.add_level(CurrentLevel);
|
||||
sghb.add_timer(GameTimer);
|
||||
sghb.add_count(++LastSaveGame);
|
||||
|
@ -426,6 +427,9 @@ bool SaveGame::Save(int slot)
|
|||
auto itemFlagsOffset = fbb.CreateVector(itemFlags);
|
||||
|
||||
flatbuffers::Offset<Save::Creature> creatureOffset;
|
||||
flatbuffers::Offset<Save::QuadBike> quadOffset;
|
||||
flatbuffers::Offset<Save::UPV> upvOffset;
|
||||
|
||||
flatbuffers::Offset<Save::Short> shortOffset;
|
||||
flatbuffers::Offset<Save::Int> intOffset;
|
||||
|
||||
|
@ -467,6 +471,45 @@ bool SaveGame::Save(int slot)
|
|||
creatureBuilder.add_ai_target_number(creature->AITargetNumber);
|
||||
creatureOffset = creatureBuilder.Finish();
|
||||
}
|
||||
else if (itemToSerialize.Data.is<QuadInfo>())
|
||||
{
|
||||
auto quad = (QuadInfo*)itemToSerialize.Data;
|
||||
|
||||
Save::QuadBikeBuilder quadBuilder{ fbb };
|
||||
|
||||
quadBuilder.add_can_start_drift(quad->CanStartDrift);
|
||||
quadBuilder.add_drift_starting(quad->DriftStarting);
|
||||
quadBuilder.add_engine_revs(quad->EngineRevs);
|
||||
quadBuilder.add_extra_rotation(quad->ExtraRotation);
|
||||
quadBuilder.add_flags(quad->Flags);
|
||||
quadBuilder.add_front_rot(quad->FrontRot);
|
||||
quadBuilder.add_left_vertical_velocity(quad->LeftVerticalVelocity);
|
||||
quadBuilder.add_momentum_angle(quad->MomentumAngle);
|
||||
quadBuilder.add_no_dismount(quad->NoDismount);
|
||||
quadBuilder.add_pitch(quad->Pitch);
|
||||
quadBuilder.add_rear_rot(quad->RearRot);
|
||||
quadBuilder.add_revs(quad->Revs);
|
||||
quadBuilder.add_right_vertical_velocity(quad->RightVerticalVelocity);
|
||||
quadBuilder.add_smoke_start(quad->SmokeStart);
|
||||
quadBuilder.add_turn_rate(quad->TurnRate);
|
||||
quadBuilder.add_velocity(quad->Velocity);
|
||||
quadOffset = quadBuilder.Finish();
|
||||
}
|
||||
else if (itemToSerialize.Data.is<UPVInfo>())
|
||||
{
|
||||
auto upv = (UPVInfo*)itemToSerialize.Data;
|
||||
|
||||
Save::UPVBuilder upvBuilder{ fbb };
|
||||
|
||||
upvBuilder.add_fan_rot(upv->FanRot);
|
||||
upvBuilder.add_flags(upv->Flags);
|
||||
upvBuilder.add_harpoon_left(upv->HarpoonLeft);
|
||||
upvBuilder.add_harpoon_timer(upv->HarpoonTimer);
|
||||
upvBuilder.add_rot(upv->Rot);
|
||||
upvBuilder.add_velocity(upv->Velocity);
|
||||
upvBuilder.add_x_rot(upv->XRot);
|
||||
upvOffset = upvBuilder.Finish();
|
||||
}
|
||||
else if (itemToSerialize.Data.is<short>())
|
||||
{
|
||||
Save::ShortBuilder sb{ fbb };
|
||||
|
@ -521,7 +564,7 @@ bool SaveGame::Save(int slot)
|
|||
serializedItem.add_ai_bits(itemToSerialize.AIBits);
|
||||
serializedItem.add_collidable(itemToSerialize.Collidable);
|
||||
serializedItem.add_looked_at(itemToSerialize.LookedAt);
|
||||
serializedItem.add_swap_mesh_flags(itemToSerialize.SwapMeshFlags);
|
||||
serializedItem.add_swap_mesh_flags(itemToSerialize.MeshSwapBits);
|
||||
|
||||
if (Objects[itemToSerialize.ObjectNumber].intelligent
|
||||
&& itemToSerialize.Data.is<CreatureInfo>())
|
||||
|
@ -529,6 +572,16 @@ bool SaveGame::Save(int slot)
|
|||
serializedItem.add_data_type(Save::ItemData::Creature);
|
||||
serializedItem.add_data(creatureOffset.Union());
|
||||
}
|
||||
else if (itemToSerialize.Data.is<QuadInfo>())
|
||||
{
|
||||
serializedItem.add_data_type(Save::ItemData::QuadBike);
|
||||
serializedItem.add_data(quadOffset.Union());
|
||||
}
|
||||
else if (itemToSerialize.Data.is<UPVInfo>())
|
||||
{
|
||||
serializedItem.add_data_type(Save::ItemData::UPV);
|
||||
serializedItem.add_data(upvOffset.Union());
|
||||
}
|
||||
else if (itemToSerialize.Data.is<short>())
|
||||
{
|
||||
serializedItem.add_data_type(Save::ItemData::Short);
|
||||
|
@ -627,6 +680,59 @@ bool SaveGame::Save(int slot)
|
|||
}
|
||||
auto staticMeshesOffset = fbb.CreateVector(staticMeshes);
|
||||
|
||||
// Particles
|
||||
std::vector<flatbuffers::Offset<Save::ParticleInfo>> particles;
|
||||
for (int i = 0; i < MAX_PARTICLES; i++)
|
||||
{
|
||||
auto* particle = &Particles[i];
|
||||
|
||||
if (!particle->on)
|
||||
continue;
|
||||
|
||||
Save::ParticleInfoBuilder particleInfo{ fbb };
|
||||
|
||||
particleInfo.add_b(particle->b);
|
||||
particleInfo.add_col_fade_speed(particle->colFadeSpeed);
|
||||
particleInfo.add_d_b(particle->dB);
|
||||
particleInfo.add_sprite_index(particle->spriteIndex);
|
||||
particleInfo.add_d_g(particle->dG);
|
||||
particleInfo.add_d_r(particle->dR);
|
||||
particleInfo.add_d_size(particle->dSize);
|
||||
particleInfo.add_dynamic(particle->dynamic);
|
||||
particleInfo.add_extras(particle->extras);
|
||||
particleInfo.add_fade_to_black(particle->fadeToBlack);
|
||||
particleInfo.add_flags(particle->flags);
|
||||
particleInfo.add_friction(particle->friction);
|
||||
particleInfo.add_fx_obj(particle->fxObj);
|
||||
particleInfo.add_g(particle->g);
|
||||
particleInfo.add_gravity(particle->gravity);
|
||||
particleInfo.add_life(particle->life);
|
||||
particleInfo.add_max_y_vel(particle->maxYvel);
|
||||
particleInfo.add_node_number(particle->nodeNumber);
|
||||
particleInfo.add_on(particle->on);
|
||||
particleInfo.add_r(particle->r);
|
||||
particleInfo.add_room_number(particle->roomNumber);
|
||||
particleInfo.add_rot_add(particle->rotAdd);
|
||||
particleInfo.add_rot_ang(particle->rotAng);
|
||||
particleInfo.add_s_b(particle->sB);
|
||||
particleInfo.add_scalar(particle->scalar);
|
||||
particleInfo.add_s_g(particle->sG);
|
||||
particleInfo.add_size(particle->size);
|
||||
particleInfo.add_s_life(particle->sLife);
|
||||
particleInfo.add_s_r(particle->sR);
|
||||
particleInfo.add_s_size(particle->sSize);
|
||||
particleInfo.add_blend_mode(particle->blendMode);
|
||||
particleInfo.add_x(particle->x);
|
||||
particleInfo.add_x_vel(particle->sSize);
|
||||
particleInfo.add_y(particle->y);
|
||||
particleInfo.add_y_vel(particle->yVel);
|
||||
particleInfo.add_z(particle->z);
|
||||
particleInfo.add_z_vel(particle->zVel);
|
||||
|
||||
particles.push_back(particleInfo.Finish());
|
||||
}
|
||||
auto particleOffset = fbb.CreateVector(particles);
|
||||
|
||||
// Particle enemies
|
||||
std::vector<flatbuffers::Offset<Save::BatInfo>> bats;
|
||||
for (int i = 0; i < NUM_BATS; i++)
|
||||
|
@ -905,6 +1011,7 @@ bool SaveGame::Save(int slot)
|
|||
sgb.add_flip_timer(0);
|
||||
sgb.add_static_meshes(staticMeshesOffset);
|
||||
sgb.add_fixed_cameras(camerasOffset);
|
||||
sgb.add_particles(particleOffset);
|
||||
sgb.add_bats(batsOffset);
|
||||
sgb.add_rats(ratsOffset);
|
||||
sgb.add_spiders(spidersOffset);
|
||||
|
@ -954,6 +1061,23 @@ bool SaveGame::Load(int slot)
|
|||
|
||||
const Save::SaveGame* s = Save::GetSaveGame(buffer.get());
|
||||
|
||||
// Statistics
|
||||
Statistics.Game.AmmoHits = s->game()->ammo_hits();
|
||||
Statistics.Game.AmmoUsed = s->game()->ammo_used();
|
||||
Statistics.Game.Distance = s->game()->distance();
|
||||
Statistics.Game.HealthUsed = s->game()->medipacks_used();
|
||||
Statistics.Game.Kills = s->game()->kills();
|
||||
Statistics.Game.Secrets = s->game()->secrets();
|
||||
Statistics.Game.Timer = s->game()->timer();
|
||||
|
||||
Statistics.Level.AmmoHits = s->level()->ammo_hits();
|
||||
Statistics.Level.AmmoUsed = s->level()->ammo_used();
|
||||
Statistics.Level.Distance = s->level()->distance();
|
||||
Statistics.Level.HealthUsed = s->level()->medipacks_used();
|
||||
Statistics.Level.Kills = s->level()->kills();
|
||||
Statistics.Level.Secrets = s->level()->secrets();
|
||||
Statistics.Level.Timer = s->level()->timer();
|
||||
|
||||
// Flipmaps
|
||||
for (int i = 0; i < s->flip_stats()->size(); i++)
|
||||
{
|
||||
|
@ -1112,6 +1236,25 @@ bool SaveGame::Load(int slot)
|
|||
item->Collidable = savedItem->collidable();
|
||||
item->LookedAt = savedItem->looked_at();
|
||||
|
||||
// Mesh stuff
|
||||
item->MeshBits = savedItem->mesh_bits();
|
||||
item->MeshSwapBits = savedItem->swap_mesh_flags();
|
||||
|
||||
if (item->ObjectNumber >= ID_SMASH_OBJECT1 && item->ObjectNumber <= ID_SMASH_OBJECT8 &&
|
||||
(item->Flags & ONESHOT))
|
||||
item->MeshBits = 0x00100;
|
||||
|
||||
// Now some post-load specific hacks for objects
|
||||
if (item->ObjectNumber >= ID_PUZZLE_HOLE1 && item->ObjectNumber <= ID_PUZZLE_HOLE16 &&
|
||||
(item->Status == ITEM_ACTIVE || item->Status == ITEM_DEACTIVATED))
|
||||
{
|
||||
item->ObjectNumber = (GAME_OBJECT_ID)((int)item->ObjectNumber + ID_PUZZLE_DONE1 - ID_PUZZLE_HOLE1);
|
||||
item->Animation.AnimNumber = Objects[item->ObjectNumber].animIndex + savedItem->anim_number();
|
||||
}
|
||||
|
||||
if (obj->floor != nullptr)
|
||||
UpdateBridgeItem(i);
|
||||
|
||||
// Creature data for intelligent items
|
||||
if (item->ObjectNumber != ID_LARA && obj->intelligent && (savedItem->flags() & (TRIGGERED | CODE_BITS | ONESHOT)))
|
||||
{
|
||||
|
@ -1151,6 +1294,41 @@ bool SaveGame::Load(int slot)
|
|||
creature->Tosspad = savedCreature->tosspad();
|
||||
SetBaddyTarget(i, savedCreature->ai_target_number());
|
||||
}
|
||||
else if (item->Data.is<QuadInfo>())
|
||||
{
|
||||
auto quad = (QuadInfo*)item->Data;
|
||||
auto savedQuad = (Save::QuadBike*)savedItem->data();
|
||||
|
||||
quad->CanStartDrift = savedQuad->can_start_drift();
|
||||
quad->DriftStarting = savedQuad->drift_starting();
|
||||
quad->EngineRevs = savedQuad->engine_revs();
|
||||
quad->ExtraRotation = savedQuad->extra_rotation();
|
||||
quad->Flags = savedQuad->flags();
|
||||
quad->FrontRot = savedQuad->front_rot();
|
||||
quad->LeftVerticalVelocity = savedQuad->left_vertical_velocity();
|
||||
quad->MomentumAngle = savedQuad->momentum_angle();
|
||||
quad->NoDismount = savedQuad->no_dismount();
|
||||
quad->Pitch = savedQuad->pitch();
|
||||
quad->RearRot = savedQuad->rear_rot();
|
||||
quad->Revs = savedQuad->revs();
|
||||
quad->RightVerticalVelocity = savedQuad->right_vertical_velocity();
|
||||
quad->SmokeStart = savedQuad->smoke_start();
|
||||
quad->TurnRate = savedQuad->turn_rate();
|
||||
quad->Velocity = savedQuad->velocity();
|
||||
}
|
||||
else if (item->Data.is<UPVInfo>())
|
||||
{
|
||||
auto upv = (UPVInfo*)item->Data;
|
||||
auto savedUpv = (Save::UPV*)savedItem->data();
|
||||
|
||||
upv->FanRot = savedUpv->fan_rot();
|
||||
upv->Flags = savedUpv->flags();
|
||||
upv->HarpoonLeft = savedUpv->harpoon_left();
|
||||
upv->HarpoonTimer = savedUpv->harpoon_timer();
|
||||
upv->Rot = savedUpv->rot();
|
||||
upv->Velocity = savedUpv->velocity();
|
||||
upv->XRot = savedUpv->x_rot();
|
||||
}
|
||||
else if (savedItem->data_type() == Save::ItemData::Short)
|
||||
{
|
||||
auto data = savedItem->data();
|
||||
|
@ -1163,29 +1341,50 @@ bool SaveGame::Load(int slot)
|
|||
auto savedData = (Save::Int*)data;
|
||||
item->Data = savedData->scalar();
|
||||
}
|
||||
|
||||
|
||||
// Mesh stuff
|
||||
item->MeshBits = savedItem->mesh_bits();
|
||||
item->SwapMeshFlags = savedItem->swap_mesh_flags();
|
||||
|
||||
// Now some post-load specific hacks for objects
|
||||
if (item->ObjectNumber >= ID_PUZZLE_HOLE1
|
||||
&& item->ObjectNumber <= ID_PUZZLE_HOLE16
|
||||
&& (item->Status == ITEM_ACTIVE
|
||||
|| item->Status == ITEM_DEACTIVATED))
|
||||
{
|
||||
item->ObjectNumber = (GAME_OBJECT_ID)((int)item->ObjectNumber + ID_PUZZLE_DONE1 - ID_PUZZLE_HOLE1);
|
||||
item->Animation.AnimNumber = Objects[item->ObjectNumber].animIndex + savedItem->anim_number();
|
||||
}
|
||||
|
||||
if ((item->ObjectNumber >= ID_SMASH_OBJECT1)
|
||||
&& (item->ObjectNumber <= ID_SMASH_OBJECT8)
|
||||
&& (item->Flags & ONESHOT))
|
||||
item->MeshBits = 0x00100;
|
||||
for (int i = 0; i < s->particles()->size(); i++)
|
||||
{
|
||||
auto particleInfo = s->particles()->Get(i);
|
||||
auto* particle = &Particles[i];
|
||||
|
||||
if (obj->floor != nullptr)
|
||||
UpdateBridgeItem(i);
|
||||
particle->x = particleInfo->x();
|
||||
particle->y = particleInfo->y();
|
||||
particle->z = particleInfo->z();
|
||||
particle->xVel = particleInfo->x_vel();
|
||||
particle->yVel = particleInfo->y_vel();
|
||||
particle->zVel = particleInfo->z_vel();
|
||||
particle->gravity = particleInfo->gravity();
|
||||
particle->rotAng = particleInfo->rot_ang();
|
||||
particle->flags = particleInfo->flags();
|
||||
particle->sSize = particleInfo->s_size();
|
||||
particle->dSize = particleInfo->d_size();
|
||||
particle->size = particleInfo->size();
|
||||
particle->friction = particleInfo->friction();
|
||||
particle->scalar = particleInfo->scalar();
|
||||
particle->spriteIndex = particleInfo->sprite_index();
|
||||
particle->rotAdd = particleInfo->rot_add();
|
||||
particle->maxYvel = particleInfo->max_y_vel();
|
||||
particle->on = particleInfo->on();
|
||||
particle->sR = particleInfo->s_r();
|
||||
particle->sG = particleInfo->s_g();
|
||||
particle->sB = particleInfo->s_b();
|
||||
particle->dR = particleInfo->d_r();
|
||||
particle->dG = particleInfo->d_g();
|
||||
particle->dB = particleInfo->d_b();
|
||||
particle->r = particleInfo->r();
|
||||
particle->g = particleInfo->g();
|
||||
particle->b = particleInfo->b();
|
||||
particle->colFadeSpeed = particleInfo->col_fade_speed();
|
||||
particle->fadeToBlack = particleInfo->fade_to_black();
|
||||
particle->sLife = particleInfo->s_life();
|
||||
particle->life = particleInfo->life();
|
||||
particle->blendMode = (BLEND_MODES)particleInfo->blend_mode();
|
||||
particle->extras = particleInfo->extras();
|
||||
particle->dynamic = particleInfo->dynamic();
|
||||
particle->fxObj = particleInfo->fx_obj();
|
||||
particle->roomNumber = particleInfo->room_number();
|
||||
particle->nodeNumber = particleInfo->node_number();
|
||||
}
|
||||
|
||||
for (int i = 0; i < s->bats()->size(); i++)
|
||||
|
|
|
@ -115,7 +115,7 @@ void InitialiseSpotCam(short Sequence)
|
|||
|
||||
AlterFOV(16380);
|
||||
|
||||
LaraItem->MeshBits = -1;
|
||||
LaraItem->MeshBits = ALL_JOINT_BITS;
|
||||
|
||||
ResetLaraFlex(LaraItem);
|
||||
|
||||
|
@ -521,7 +521,7 @@ void CalculateSpotCameras()
|
|||
}
|
||||
}
|
||||
|
||||
LookAt(&Camera, 0);
|
||||
LookAt(&Camera, croll);
|
||||
|
||||
if (CheckTrigger)
|
||||
{
|
||||
|
@ -814,6 +814,9 @@ void CalculateSpotCameras()
|
|||
|
||||
SplineToCamera = 1;
|
||||
}
|
||||
|
||||
if (CurrentSplineCamera > LastCamera)
|
||||
CurrentSplineCamera = LastCamera;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "Objects/TR4/Entity/tr4_mutant.h"
|
||||
#include "Objects/TR4/Entity/tr4_demigod.h"
|
||||
#include "Specific/level.h"
|
||||
#include "Renderer/Renderer11Enums.h"
|
||||
|
||||
using namespace TEN::Effects::Lara;
|
||||
using namespace TEN::Entities::TR4;
|
||||
|
@ -29,7 +30,7 @@ namespace TEN::Entities::Effects
|
|||
if (dx >= -SECTOR(16) && dx <= SECTOR(16) &&
|
||||
dz >= -SECTOR(16) && dz <= SECTOR(16))
|
||||
{
|
||||
auto* spark = &Sparks[GetFreeSpark()];
|
||||
auto* spark = GetFreeParticle();
|
||||
|
||||
spark->on = 1;
|
||||
spark->sR = 0;
|
||||
|
@ -40,7 +41,7 @@ namespace TEN::Entities::Effects
|
|||
spark->dG = spark->dB + 64;
|
||||
spark->fadeToBlack = 8;
|
||||
spark->colFadeSpeed = (GetRandomControl() & 3) + 4;
|
||||
spark->transType = TransTypeEnum::COLADD;
|
||||
spark->blendMode = BLEND_MODES::BLENDMODE_ADDITIVE;
|
||||
spark->life = spark->sLife = (GetRandomControl() & 3) + 16;
|
||||
spark->y = 0;
|
||||
spark->x = (GetRandomControl() & 0xF) - 8;
|
||||
|
@ -80,7 +81,7 @@ namespace TEN::Entities::Effects
|
|||
|
||||
if (dx >= -16384 && dx <= 16384 && dz >= -16384 && dz <= 16384)
|
||||
{
|
||||
auto* spark = &Sparks[GetFreeSpark()];
|
||||
auto* spark = GetFreeParticle();
|
||||
|
||||
spark->on = 1;
|
||||
spark->sR = 0;
|
||||
|
@ -90,7 +91,7 @@ namespace TEN::Entities::Effects
|
|||
spark->dG = spark->dR = (GetRandomControl() & 0x7F) + 32;
|
||||
spark->fadeToBlack = 8;
|
||||
spark->colFadeSpeed = (GetRandomControl() & 3) + 4;
|
||||
spark->transType = TransTypeEnum::COLADD;
|
||||
spark->blendMode = BLEND_MODES::BLENDMODE_ADDITIVE;
|
||||
spark->life = spark->sLife = (GetRandomControl() & 3) + 16;
|
||||
spark->y = 0;
|
||||
spark->x = (GetRandomControl() & 0xF) - 8;
|
||||
|
|
|
@ -107,7 +107,7 @@ namespace TEN::Entities::Effects
|
|||
}
|
||||
|
||||
if (item->ItemFlags[2])
|
||||
AddFire(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, SP_NORMALFIRE, item->RoomNumber, item->ItemFlags[2]);
|
||||
AddFire(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, item->RoomNumber, 0.5f, item->ItemFlags[2]);
|
||||
|
||||
if (item->ItemFlags[1])
|
||||
{
|
||||
|
@ -143,7 +143,7 @@ namespace TEN::Entities::Effects
|
|||
if (item->TriggerFlags < 8)
|
||||
FlameEmitterFlags[item->TriggerFlags] = true;
|
||||
|
||||
AddFire(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, SP_BIGFIRE, item->RoomNumber, 0);
|
||||
AddFire(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, item->RoomNumber, 1.0f, 0);
|
||||
|
||||
TriggerDynamicLight(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z,
|
||||
16 - (GetRandomControl() & 1),
|
||||
|
@ -171,7 +171,7 @@ namespace TEN::Entities::Effects
|
|||
|
||||
void FlameEmitter2Control(short itemNumber)
|
||||
{
|
||||
ItemInfo* item = &g_Level.Items[itemNumber];
|
||||
auto* item = &g_Level.Items[itemNumber];
|
||||
|
||||
if (TriggerActive(item))
|
||||
{
|
||||
|
@ -184,10 +184,29 @@ namespace TEN::Entities::Effects
|
|||
if (item->TriggerFlags == 123)
|
||||
{
|
||||
// Middle of the block
|
||||
AddFire(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, SP_SMALLFIRE, item->RoomNumber, item->ItemFlags[3]);
|
||||
AddFire(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, item->RoomNumber, 0.25f, item->ItemFlags[3]);
|
||||
}
|
||||
else
|
||||
AddFire(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, SP_SMALLFIRE - item->TriggerFlags, item->RoomNumber, item->ItemFlags[3]);
|
||||
{
|
||||
float size = 1.0f;
|
||||
switch (item->TriggerFlags)
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
size = 2.0f;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
size = 1.0f;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
size = 0.5f;
|
||||
break;
|
||||
}
|
||||
|
||||
AddFire(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, item->RoomNumber, size, item->ItemFlags[3]);
|
||||
}
|
||||
}
|
||||
|
||||
if (item->TriggerFlags == 0 || item->TriggerFlags == 2)
|
||||
|
@ -212,31 +231,28 @@ namespace TEN::Entities::Effects
|
|||
|
||||
if (item->TriggerFlags == 2)
|
||||
{
|
||||
item->Pose.Position.x += phd_sin(item->Pose.Orientation.y - ANGLE(180));
|
||||
item->Pose.Position.z += phd_cos(item->Pose.Orientation.y - ANGLE(180));
|
||||
item->Pose.Position.x += phd_sin(item->Pose.Orientation.y - ANGLE(180)) * (CLICK(1) / FPS);
|
||||
item->Pose.Position.z += phd_cos(item->Pose.Orientation.y - ANGLE(180)) * (CLICK(1) / FPS);
|
||||
|
||||
short roomNumber = item->RoomNumber;
|
||||
FloorInfo* floor = GetFloor(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, &roomNumber);
|
||||
auto probe = GetCollision(item);
|
||||
|
||||
if (g_Level.Rooms[roomNumber].flags & ENV_FLAG_WATER)
|
||||
if (TestEnvironment(ENV_FLAG_WATER, probe.RoomNumber) ||
|
||||
probe.Position.Floor - item->Pose.Position.y > CLICK(2) ||
|
||||
probe.Position.Floor == NO_HEIGHT)
|
||||
{
|
||||
Weather.Flash(255, 128, 0, 0.03f);
|
||||
KillItem(itemNumber);
|
||||
return;
|
||||
}
|
||||
|
||||
if (item->RoomNumber != roomNumber)
|
||||
{
|
||||
ItemNewRoom(itemNumber, roomNumber);
|
||||
}
|
||||
if (item->RoomNumber != probe.RoomNumber)
|
||||
ItemNewRoom(itemNumber, probe.RoomNumber);
|
||||
|
||||
item->Pose.Position.y = GetFloorHeight(floor, item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z);;
|
||||
item->Pose.Position.y = probe.Position.Floor;
|
||||
|
||||
if (Wibble & 7)
|
||||
{
|
||||
TriggerFireFlame(item->Pose.Position.x, item->Pose.Position.y - 32, item->Pose.Position.z, -1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
SoundEffect(SFX_TR4_LOOP_FOR_SMALL_FIRES, &item->Pose);
|
||||
}
|
||||
|
@ -251,7 +267,7 @@ namespace TEN::Entities::Effects
|
|||
|
||||
void FlameControl(short fxNumber)
|
||||
{
|
||||
FX_INFO* fx = &EffectList[fxNumber];
|
||||
auto* fx = &EffectList[fxNumber];
|
||||
|
||||
for (int i = 0; i < 14; i++)
|
||||
{
|
||||
|
@ -279,7 +295,7 @@ namespace TEN::Entities::Effects
|
|||
byte g = (GetRandomControl() & 0x1F) + 96;
|
||||
byte b;
|
||||
|
||||
Vector3Int pos{ 0,0,0 };
|
||||
auto pos = Vector3Int();
|
||||
GetLaraJointPosition(&pos, LM_HIPS);
|
||||
|
||||
if (!Lara.BurnSmoke)
|
||||
|
@ -333,8 +349,8 @@ namespace TEN::Entities::Effects
|
|||
if (LaraItem->RoomNumber != fx->roomNumber)
|
||||
EffectNewRoom(fxNumber, LaraItem->RoomNumber);
|
||||
|
||||
int wh = GetWaterHeight(fx->pos.Position.x, fx->pos.Position.y, fx->pos.Position.z, fx->roomNumber);
|
||||
if (wh == NO_HEIGHT || fx->pos.Position.y <= wh || Lara.BurnBlue)
|
||||
int waterHeight = GetWaterHeight(fx->pos.Position.x, fx->pos.Position.y, fx->pos.Position.z, fx->roomNumber);
|
||||
if (waterHeight == NO_HEIGHT || fx->pos.Position.y <= waterHeight || Lara.BurnBlue)
|
||||
{
|
||||
SoundEffect(SFX_TR4_LOOP_FOR_SMALL_FIRES, &fx->pos);
|
||||
|
||||
|
@ -356,7 +372,7 @@ namespace TEN::Entities::Effects
|
|||
|
||||
void InitialiseFlameEmitter(short itemNumber)
|
||||
{
|
||||
ItemInfo* item = &g_Level.Items[itemNumber];
|
||||
auto* item = &g_Level.Items[itemNumber];
|
||||
|
||||
if (item->TriggerFlags < 0)
|
||||
{
|
||||
|
@ -389,7 +405,7 @@ namespace TEN::Entities::Effects
|
|||
|
||||
void InitialiseFlameEmitter2(short itemNumber)
|
||||
{
|
||||
ItemInfo* item = &g_Level.Items[itemNumber];
|
||||
auto* item = &g_Level.Items[itemNumber];
|
||||
|
||||
item->Pose.Position.y -= 64;
|
||||
|
||||
|
@ -402,6 +418,7 @@ namespace TEN::Entities::Effects
|
|||
item->Pose.Position.z += 80;
|
||||
else
|
||||
item->Pose.Position.z += 256;
|
||||
|
||||
break;
|
||||
|
||||
case 0x4000:
|
||||
|
@ -409,6 +426,7 @@ namespace TEN::Entities::Effects
|
|||
item->Pose.Position.x += 80;
|
||||
else
|
||||
item->Pose.Position.x += 256;
|
||||
|
||||
break;
|
||||
|
||||
case -0x8000:
|
||||
|
@ -416,6 +434,7 @@ namespace TEN::Entities::Effects
|
|||
item->Pose.Position.z -= 80;
|
||||
else
|
||||
item->Pose.Position.z -= 256;
|
||||
|
||||
break;
|
||||
|
||||
case -0x4000:
|
||||
|
@ -423,6 +442,7 @@ namespace TEN::Entities::Effects
|
|||
item->Pose.Position.x -= 80;
|
||||
else
|
||||
item->Pose.Position.x -= 256;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -430,13 +450,13 @@ namespace TEN::Entities::Effects
|
|||
|
||||
void InitialiseFlameEmitter3(short itemNumber)
|
||||
{
|
||||
ItemInfo* item = &g_Level.Items[itemNumber];
|
||||
auto* item = &g_Level.Items[itemNumber];
|
||||
|
||||
if (item->TriggerFlags >= 3)
|
||||
{
|
||||
for (int i = 0; i < g_Level.NumItems; i++)
|
||||
{
|
||||
ItemInfo* currentItem = &g_Level.Items[i];
|
||||
auto* currentItem = &g_Level.Items[i];
|
||||
|
||||
if (currentItem->ObjectNumber == ID_ANIMATING3)
|
||||
{
|
||||
|
@ -451,24 +471,20 @@ namespace TEN::Entities::Effects
|
|||
|
||||
void FlameEmitter3Control(short itemNumber)
|
||||
{
|
||||
ItemInfo* item = &g_Level.Items[itemNumber];
|
||||
auto* item = &g_Level.Items[itemNumber];
|
||||
|
||||
if (TriggerActive(item))
|
||||
{
|
||||
if (item->TriggerFlags)
|
||||
{
|
||||
SoundEffect(SFX_TR4_ELEC_ARCING_LOOP, &item->Pose);
|
||||
SoundEffect(SFX_TR4_ELECTRIC_ARCING_LOOP, &item->Pose);
|
||||
|
||||
byte g = (GetRandomControl() & 0x3F) + 192;
|
||||
byte b = (GetRandomControl() & 0x3F) + 192;
|
||||
|
||||
Vector3Int src;
|
||||
auto src = item->Pose.Position;
|
||||
Vector3Int dest;
|
||||
|
||||
src.x = item->Pose.Position.x;
|
||||
src.y = item->Pose.Position.y;
|
||||
src.z = item->Pose.Position.z;
|
||||
|
||||
if (!(GlobalCounter & 3))
|
||||
{
|
||||
if (item->TriggerFlags == 2 || item->TriggerFlags == 4)
|
||||
|
@ -511,11 +527,9 @@ namespace TEN::Entities::Effects
|
|||
if (item->TriggerFlags >= 3 && !(GlobalCounter & 1))
|
||||
{
|
||||
short targetItemNumber = item->ItemFlags[((GlobalCounter >> 2) & 1) + 2];
|
||||
ItemInfo* targetItem = &g_Level.Items[targetItemNumber];
|
||||
auto* targetItem = &g_Level.Items[targetItemNumber];
|
||||
|
||||
dest.x = 0;
|
||||
dest.y = -64;
|
||||
dest.z = 20;
|
||||
dest = Vector3Int(0, -64, 20);
|
||||
GetJointAbsPosition(targetItem, &dest, 0);
|
||||
|
||||
if (!(GlobalCounter & 3))
|
||||
|
@ -549,19 +563,20 @@ namespace TEN::Entities::Effects
|
|||
5);
|
||||
}
|
||||
}
|
||||
|
||||
if (item->TriggerFlags != 3 || targetItem->TriggerFlags)
|
||||
TriggerLightningGlow(dest.x, dest.y, dest.z, 64, 0, g, b);
|
||||
}
|
||||
|
||||
if ((GlobalCounter & 3) == 2)
|
||||
{
|
||||
src.x = item->Pose.Position.x;
|
||||
src.y = item->Pose.Position.y;
|
||||
src.z = item->Pose.Position.z;
|
||||
src = item->Pose.Position;
|
||||
|
||||
dest.x = (GetRandomControl() & 0x1FF) + src.x - 256;
|
||||
dest.y = (GetRandomControl() & 0x1FF) + src.y - 256;
|
||||
dest.z = (GetRandomControl() & 0x1FF) + src.z - 256;
|
||||
dest = Vector3Int(
|
||||
(GetRandomControl() & 0x1FF) + src.x - 256,
|
||||
(GetRandomControl() & 0x1FF) + src.y - 256,
|
||||
(GetRandomControl() & 0x1FF) + src.z - 256
|
||||
);
|
||||
|
||||
TriggerLightning(
|
||||
&src,
|
||||
|
@ -581,9 +596,7 @@ namespace TEN::Entities::Effects
|
|||
{
|
||||
// Small fires
|
||||
if (item->ItemFlags[0] != 0)
|
||||
{
|
||||
item->ItemFlags[0]--;
|
||||
}
|
||||
else
|
||||
{
|
||||
item->ItemFlags[0] = (GetRandomControl() & 3) + 8;
|
||||
|
@ -614,10 +627,7 @@ namespace TEN::Entities::Effects
|
|||
|
||||
TriggerDynamicLight(x, item->Pose.Position.y, z, 12, (GetRandomControl() & 0x3F) + 192, ((GetRandomControl() >> 4) & 0x1F) + 96, 0);
|
||||
|
||||
PHD_3DPOS pos;
|
||||
pos.Position.x = item->Pose.Position.x;
|
||||
pos.Position.y = item->Pose.Position.y;
|
||||
pos.Position.z = item->Pose.Position.z;
|
||||
auto pos = PHD_3DPOS(item->Pose.Position);
|
||||
|
||||
if (ItemNearLara(&pos, 600))
|
||||
{
|
||||
|
@ -637,22 +647,22 @@ namespace TEN::Entities::Effects
|
|||
}
|
||||
}
|
||||
|
||||
void FlameEmitterCollision(short itemNumber, ItemInfo* l, CollisionInfo* coll)
|
||||
void FlameEmitterCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll)
|
||||
{
|
||||
ItemInfo* item = &g_Level.Items[itemNumber];
|
||||
auto* item = &g_Level.Items[itemNumber];
|
||||
|
||||
if (Lara.Control.Weapon.GunType != LaraWeaponType::Torch
|
||||
|| Lara.Control.HandStatus != HandStatus::WeaponReady
|
||||
|| Lara.LeftArm.Locked
|
||||
|| Lara.Torch.IsLit == (item->Status & 1)
|
||||
|| item->Timer == -1
|
||||
|| !(TrInput & IN_ACTION)
|
||||
|| l->Animation.ActiveState != LS_IDLE
|
||||
|| l->Animation.AnimNumber != LA_STAND_IDLE
|
||||
|| l->Animation.Airborne)
|
||||
if (Lara.Control.Weapon.GunType != LaraWeaponType::Torch ||
|
||||
Lara.Control.HandStatus != HandStatus::WeaponReady ||
|
||||
Lara.LeftArm.Locked ||
|
||||
Lara.Torch.IsLit == (item->Status & 1) ||
|
||||
item->Timer == -1 ||
|
||||
!(TrInput & IN_ACTION) ||
|
||||
laraItem->Animation.ActiveState != LS_IDLE ||
|
||||
laraItem->Animation.AnimNumber != LA_STAND_IDLE ||
|
||||
laraItem->Animation.Airborne)
|
||||
{
|
||||
if (item->ObjectNumber == ID_BURNING_ROOTS)
|
||||
ObjectCollision(itemNumber, l, coll);
|
||||
ObjectCollision(itemNumber, laraItem, coll);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -684,28 +694,25 @@ namespace TEN::Entities::Effects
|
|||
FireBounds.boundingBox.Z1 = -384;
|
||||
FireBounds.boundingBox.Z2 = 384;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
short oldYrot = item->Pose.Orientation.y;
|
||||
item->Pose.Orientation.y = l->Pose.Orientation.y;
|
||||
item->Pose.Orientation.y = laraItem->Pose.Orientation.y;
|
||||
|
||||
if (TestLaraPosition(&FireBounds, item, l))
|
||||
if (TestLaraPosition(&FireBounds, item, laraItem))
|
||||
{
|
||||
if (item->ObjectNumber == ID_BURNING_ROOTS)
|
||||
{
|
||||
l->Animation.AnimNumber = LA_TORCH_LIGHT_5;
|
||||
}
|
||||
laraItem->Animation.AnimNumber = LA_TORCH_LIGHT_5;
|
||||
else
|
||||
{
|
||||
Lara.Torch.State = TorchState::JustLit;
|
||||
int dy = abs(l->Pose.Position.y - item->Pose.Position.y);
|
||||
l->ItemFlags[3] = 1;
|
||||
l->Animation.AnimNumber = (dy >> 8) + LA_TORCH_LIGHT_1;
|
||||
int dy = abs(laraItem->Pose.Position.y - item->Pose.Position.y);
|
||||
laraItem->ItemFlags[3] = 1;
|
||||
laraItem->Animation.AnimNumber = (dy >> 8) + LA_TORCH_LIGHT_1;
|
||||
}
|
||||
|
||||
l->Animation.ActiveState = LS_MISC_CONTROL;
|
||||
l->Animation.FrameNumber = g_Level.Anims[l->Animation.AnimNumber].frameBase;
|
||||
laraItem->Animation.ActiveState = LS_MISC_CONTROL;
|
||||
laraItem->Animation.FrameNumber = g_Level.Anims[laraItem->Animation.AnimNumber].frameBase;
|
||||
Lara.Flare.ControlLeft = false;
|
||||
Lara.LeftArm.Locked = true;
|
||||
Lara.InteractedItem = itemNumber;
|
||||
|
@ -714,13 +721,13 @@ namespace TEN::Entities::Effects
|
|||
item->Pose.Orientation.y = oldYrot;
|
||||
}
|
||||
|
||||
if (Lara.InteractedItem == itemNumber
|
||||
&& item->Status != ITEM_ACTIVE
|
||||
&& l->Animation.ActiveState == LS_MISC_CONTROL)
|
||||
if (Lara.InteractedItem == itemNumber &&
|
||||
item->Status != ITEM_ACTIVE &&
|
||||
laraItem->Animation.ActiveState == LS_MISC_CONTROL)
|
||||
{
|
||||
if (l->Animation.AnimNumber >= LA_TORCH_LIGHT_1 && l->Animation.AnimNumber <= LA_TORCH_LIGHT_5)
|
||||
if (laraItem->Animation.AnimNumber >= LA_TORCH_LIGHT_1 && laraItem->Animation.AnimNumber <= LA_TORCH_LIGHT_5)
|
||||
{
|
||||
if (l->Animation.FrameNumber - g_Level.Anims[l->Animation.AnimNumber].frameBase == 40)
|
||||
if (laraItem->Animation.FrameNumber - g_Level.Anims[laraItem->Animation.AnimNumber].frameBase == 40)
|
||||
{
|
||||
TestTriggers(item, true, item->Flags & IFLAG_ACTIVATION_MASK);
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ using namespace TEN::Effects::Lara;
|
|||
|
||||
void TriggerElectricityWireSparks(int x, int z, byte objNum, byte node, bool glow)
|
||||
{
|
||||
SPARKS* spark = &Sparks[GetFreeSpark()];
|
||||
auto* spark = GetFreeParticle();
|
||||
spark->on = true;
|
||||
spark->sR = 255;
|
||||
spark->sG = 255;
|
||||
|
@ -43,7 +43,7 @@ void TriggerElectricityWireSparks(int x, int z, byte objNum, byte node, bool glo
|
|||
}
|
||||
|
||||
spark->fxObj = objNum;
|
||||
spark->transType = TransTypeEnum::COLADD;
|
||||
spark->blendMode = BLEND_MODES::BLENDMODE_ADDITIVE;
|
||||
spark->flags = SP_ITEM | SP_NODEATTACH | SP_SCALE | SP_DEF;
|
||||
spark->nodeNumber = node;
|
||||
spark->x = x;
|
||||
|
@ -71,13 +71,13 @@ void TriggerElectricityWireSparks(int x, int z, byte objNum, byte node, bool glo
|
|||
if (glow)
|
||||
{
|
||||
spark->scalar = 1;
|
||||
spark->def = Objects[ID_DEFAULT_SPRITES].meshIndex + 11;
|
||||
spark->spriteIndex = Objects[ID_DEFAULT_SPRITES].meshIndex + 11;
|
||||
spark->size = spark->sSize = (GetRandomControl() & 0x1F) + 160;
|
||||
}
|
||||
else
|
||||
{
|
||||
spark->scalar = 0;
|
||||
spark->def = Objects[ID_DEFAULT_SPRITES].meshIndex + 14;
|
||||
spark->spriteIndex = Objects[ID_DEFAULT_SPRITES].meshIndex + 14;
|
||||
spark->size = spark->sSize = (GetRandomControl() & 7) + 8;
|
||||
}
|
||||
|
||||
|
@ -89,7 +89,7 @@ void TriggerElectricitySparks(ItemInfo* item, int joint, int flame)
|
|||
Vector3Int pos = { 0, 0, 0 };
|
||||
GetJointAbsPosition(item, &pos, joint);
|
||||
|
||||
SPARKS* spark = &Sparks[GetFreeSpark()];
|
||||
auto* spark = GetFreeParticle();
|
||||
|
||||
spark->on = 1;
|
||||
spark->dR = 0;
|
||||
|
@ -100,7 +100,7 @@ void TriggerElectricitySparks(ItemInfo* item, int joint, int flame)
|
|||
spark->sG = color;
|
||||
spark->dB = color;
|
||||
spark->dG = color / 2;
|
||||
spark->transType = TransTypeEnum::COLADD;
|
||||
spark->blendMode = BLEND_MODES::BLENDMODE_ADDITIVE;
|
||||
spark->fadeToBlack = 4;
|
||||
spark->life = 12;
|
||||
spark->sLife = 12;
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "Game/collision/collide_room.h"
|
||||
#include "Game/collision/collide_item.h"
|
||||
#include "Game/control/los.h"
|
||||
#include "Renderer/Renderer11Enums.h"
|
||||
|
||||
using namespace TEN::Entities::Effects;
|
||||
|
||||
|
@ -21,7 +22,7 @@ namespace TEN::Entities::Generic
|
|||
{
|
||||
void TriggerTorchFlame(char fxObj, char node)
|
||||
{
|
||||
auto* spark = &Sparks[GetFreeSpark()];
|
||||
auto* spark = GetFreeParticle();
|
||||
|
||||
spark->on = true;
|
||||
|
||||
|
@ -34,7 +35,7 @@ namespace TEN::Entities::Generic
|
|||
|
||||
spark->fadeToBlack = 8;
|
||||
spark->colFadeSpeed = (GetRandomControl() & 3) + 12;
|
||||
spark->transType = TransTypeEnum::COLADD;
|
||||
spark->blendMode = BLEND_MODES::BLENDMODE_ADDITIVE;
|
||||
spark->life = spark->sLife = (GetRandomControl() & 7) + 24;
|
||||
|
||||
spark->x = (GetRandomControl() & 0xF) - 8;
|
||||
|
@ -81,8 +82,8 @@ namespace TEN::Entities::Generic
|
|||
Lara.Torch.State = TorchState::Dropping;
|
||||
}
|
||||
else if (TrInput & IN_DRAW &&
|
||||
!LaraItem->Animation.VerticalVelocity &&
|
||||
!LaraItem->Animation.Airborne &&
|
||||
!LaraItem->Animation.VerticalVelocity &&
|
||||
LaraItem->Animation.ActiveState != LS_JUMP_PREPARE &&
|
||||
LaraItem->Animation.ActiveState != LS_JUMP_UP &&
|
||||
LaraItem->Animation.ActiveState != LS_JUMP_FORWARD &&
|
||||
|
@ -185,11 +186,11 @@ namespace TEN::Entities::Generic
|
|||
if (Lara.Control.Weapon.GunType == LaraWeaponType::Flare)
|
||||
CreateFlare(LaraItem, ID_FLARE_ITEM, false);
|
||||
|
||||
Lara.Control.HandStatus = HandStatus::WeaponReady;
|
||||
Lara.Control.Weapon.RequestGunType = LaraWeaponType::Torch;
|
||||
Lara.Control.Weapon.GunType = LaraWeaponType::Torch;
|
||||
Lara.Flare.ControlLeft = true;
|
||||
Lara.LeftArm.AnimNumber = Objects[ID_LARA_TORCH_ANIM].animIndex;
|
||||
Lara.Control.HandStatus = HandStatus::WeaponReady;
|
||||
Lara.LeftArm.Locked = false;
|
||||
Lara.LeftArm.FrameNumber = 0;
|
||||
Lara.LeftArm.FrameBase = g_Level.Anims[Lara.LeftArm.AnimNumber].framePtr;
|
||||
|
@ -201,25 +202,28 @@ namespace TEN::Entities::Generic
|
|||
{
|
||||
auto* item = &g_Level.Items[itemNumber];
|
||||
|
||||
int oldX = item->Pose.Position.x;
|
||||
int oldY = item->Pose.Position.y;
|
||||
int oldZ = item->Pose.Position.z;
|
||||
|
||||
if (item->Animation.VerticalVelocity)
|
||||
item->Pose.Orientation.z += ANGLE(5);
|
||||
{
|
||||
item->Pose.Orientation.x -= ANGLE(5.0f);
|
||||
item->Pose.Orientation.z += ANGLE(5.0f);
|
||||
}
|
||||
else if (!item->Animation.Velocity)
|
||||
{
|
||||
item->Pose.Orientation.x = 0;
|
||||
item->Pose.Orientation.z = 0;
|
||||
}
|
||||
|
||||
int xv = item->Animation.Velocity * phd_sin(item->Pose.Orientation.y);
|
||||
int zv = item->Animation.Velocity * phd_cos(item->Pose.Orientation.y);
|
||||
auto velocity = Vector3Int(
|
||||
item->Animation.Velocity * phd_sin(item->Pose.Orientation.y),
|
||||
item->Animation.VerticalVelocity,
|
||||
item->Animation.Velocity * phd_cos(item->Pose.Orientation.y)
|
||||
);
|
||||
|
||||
item->Pose.Position.x += xv;
|
||||
item->Pose.Position.z += zv;
|
||||
auto oldPos = item->Pose.Position;
|
||||
item->Pose.Position += Vector3Int(velocity.x, 0, velocity.z);
|
||||
|
||||
if (g_Level.Rooms[item->RoomNumber].flags & ENV_FLAG_WATER)
|
||||
if (TestEnvironment(ENV_FLAG_WATER, item) ||
|
||||
TestEnvironment(ENV_FLAG_SWAMP, item))
|
||||
{
|
||||
item->Animation.VerticalVelocity += (5 - item->Animation.VerticalVelocity) / 2;
|
||||
item->Animation.Velocity += (5 - item->Animation.Velocity) / 2;
|
||||
|
@ -231,22 +235,24 @@ namespace TEN::Entities::Generic
|
|||
item->Animation.VerticalVelocity += 6;
|
||||
|
||||
item->Pose.Position.y += item->Animation.VerticalVelocity;
|
||||
DoProjectileDynamics(itemNumber, oldPos.x, oldPos.y, oldPos.z, velocity.x, velocity.y, velocity.z);
|
||||
|
||||
DoProjectileDynamics(itemNumber, oldX, oldY, oldZ, xv, item->Animation.VerticalVelocity, zv);
|
||||
|
||||
if (GetCollidedObjects(item, 0, true, CollidedItems, CollidedMeshes, 0))
|
||||
// Collide with entities.
|
||||
if (GetCollidedObjects(item, 0, true, CollidedItems, CollidedMeshes, true))
|
||||
{
|
||||
LaraCollision.Setup.EnableObjectPush = true;
|
||||
if (CollidedItems)
|
||||
{
|
||||
if (!Objects[CollidedItems[0]->ObjectNumber].intelligent
|
||||
&& CollidedItems[0]->ObjectNumber != ID_LARA)
|
||||
if (!Objects[CollidedItems[0]->ObjectNumber].intelligent &&
|
||||
CollidedItems[0]->ObjectNumber != ID_LARA)
|
||||
{
|
||||
ObjectCollision(CollidedItems[0] - g_Level.Items.data(), item, &LaraCollision);
|
||||
}
|
||||
}
|
||||
else
|
||||
ItemPushStatic(item, CollidedMeshes[0], &LaraCollision);
|
||||
|
||||
item->Animation.Velocity >>= 1;
|
||||
item->Animation.Velocity /= 2;
|
||||
}
|
||||
|
||||
if (item->ItemFlags[3])
|
||||
|
@ -262,16 +268,18 @@ namespace TEN::Entities::Generic
|
|||
|
||||
void LaraTorch(Vector3Int* src, Vector3Int* target, int rot, int color)
|
||||
{
|
||||
GameVector pos1;
|
||||
pos1.x = src->x;
|
||||
pos1.y = src->y;
|
||||
pos1.z = src->z;
|
||||
pos1.roomNumber = LaraItem->RoomNumber;
|
||||
auto pos1 = GameVector(
|
||||
src->x,
|
||||
src->y,
|
||||
src->z,
|
||||
LaraItem->RoomNumber
|
||||
);
|
||||
|
||||
GameVector pos2;
|
||||
pos2.x = target->x;
|
||||
pos2.y = target->y;
|
||||
pos2.z = target->z;
|
||||
auto pos2 = GameVector(
|
||||
target->x,
|
||||
target->y,
|
||||
target->z
|
||||
);
|
||||
|
||||
TriggerDynamicLight(pos1.x, pos1.y, pos1.z, 12, color, color, color >> 1);
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "Specific/input.h"
|
||||
#include "Sound/sound.h"
|
||||
#include "Game/collision/collide_item.h"
|
||||
#include "Renderer/Renderer11Enums.h"
|
||||
|
||||
OBJECT_TEXTURE* WaterfallTextures[6];
|
||||
float WaterfallY[6];
|
||||
|
@ -347,7 +348,7 @@ void HighObject2Control(short itemNumber)
|
|||
|
||||
if (--item->ItemFlags[2] < 15)
|
||||
{
|
||||
auto* spark = &Sparks[GetFreeSpark()];
|
||||
auto* spark = GetFreeParticle();
|
||||
spark->on = 1;
|
||||
spark->sR = -1;
|
||||
spark->sB = 16;
|
||||
|
@ -357,7 +358,7 @@ void HighObject2Control(short itemNumber)
|
|||
spark->dG = (GetRandomControl() & 0x3F) + -128;
|
||||
spark->fadeToBlack = 4;
|
||||
spark->colFadeSpeed = (GetRandomControl() & 3) + 4;
|
||||
spark->transType = TransTypeEnum::COLADD;
|
||||
spark->blendMode = BLEND_MODES::BLENDMODE_ADDITIVE;
|
||||
spark->life = spark->sLife = (GetRandomControl() & 3) + 24;
|
||||
spark->x = item->ItemFlags[1] + (GetRandomControl() & 0x3F) + item->Pose.Position.x - 544;
|
||||
spark->y = item->Pose.Position.y;
|
||||
|
@ -381,7 +382,7 @@ void HighObject2Control(short itemNumber)
|
|||
else
|
||||
{
|
||||
spark->flags = SP_ROTATE | SP_DEF | SP_SCALE;
|
||||
spark->def = Objects[ID_DEFAULT_SPRITES].meshIndex + SPR_UNDERWATERDUST;
|
||||
spark->spriteIndex = Objects[ID_DEFAULT_SPRITES].meshIndex + SPR_UNDERWATERDUST;
|
||||
spark->scalar = 1;
|
||||
spark->gravity = (GetRandomControl() & 0xF) + 64;
|
||||
}
|
||||
|
|
|
@ -692,7 +692,7 @@ namespace TEN::Entities::Generic
|
|||
|
||||
if (item->Animation.AnimNumber == LA_ROPE_DOWN && item->Animation.FrameNumber == g_Level.Anims[item->Animation.AnimNumber].frameEnd)
|
||||
{
|
||||
SoundEffect(SFX_TR4_LARA_POLE_LOOP, &LaraItem->Pose);
|
||||
SoundEffect(SFX_TR4_LARA_POLE_SLIDE_LOOP, &LaraItem->Pose);
|
||||
item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase;
|
||||
Lara.Control.Rope.Flag = 0;
|
||||
++Lara.Control.Rope.Segment;
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "Game/effects/effects.h"
|
||||
#include "Game/items.h"
|
||||
#include "Sound/sound.h"
|
||||
#include "Renderer/Renderer11Enums.h"
|
||||
|
||||
namespace TEN::Entities::Traps
|
||||
{
|
||||
|
@ -138,7 +139,7 @@ namespace TEN::Entities::Traps
|
|||
AddActiveItem(dartItemNumber);
|
||||
dartItem->Status = ITEM_ACTIVE;
|
||||
|
||||
SoundEffect(SFX_TR4_DART_SPITT, &dartItem->Pose);
|
||||
SoundEffect(SFX_TR4_DART_SPIT, &dartItem->Pose);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -150,7 +151,7 @@ namespace TEN::Entities::Traps
|
|||
if (dx < -16384 || dx > 16384 || dz < -16384 || dz > 16384)
|
||||
return;
|
||||
|
||||
SPARKS* spark = &Sparks[GetFreeSpark()];
|
||||
auto* spark = GetFreeParticle();
|
||||
|
||||
spark->on = true;
|
||||
|
||||
|
@ -165,7 +166,7 @@ namespace TEN::Entities::Traps
|
|||
spark->colFadeSpeed = 8;
|
||||
spark->fadeToBlack = 4;
|
||||
|
||||
spark->transType = TransTypeEnum::COLADD;
|
||||
spark->blendMode = BLEND_MODES::BLENDMODE_ADDITIVE;
|
||||
|
||||
spark->life = spark->sLife = (GetRandomControl() & 3) + 32;
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ constexpr auto FALLINGBLOCK_FALL_VELOCITY = 4;
|
|||
constexpr auto FALLINGBLOCK_FALL_ROTATION_SPEED = 1;
|
||||
constexpr auto FALLINGBLOCK_DELAY = 52;
|
||||
constexpr auto FALLINGBLOCK_WIBBLE = 3;
|
||||
constexpr auto FALLINGBLOCK_HEIGHT_TOLERANCE = 8;
|
||||
constexpr auto FALLINGBLOCK_CRUMBLE_DELAY = 100;
|
||||
|
||||
void InitialiseFallingBlock(short itemNumber)
|
||||
|
@ -36,7 +37,7 @@ void InitialiseFallingBlock(short itemNumber)
|
|||
void FallingBlockCollision(short itemNum, ItemInfo* l, CollisionInfo* coll)
|
||||
{
|
||||
ItemInfo* item = &g_Level.Items[itemNum];
|
||||
if (!item->ItemFlags[0] && !item->TriggerFlags && item->Pose.Position.y == l->Pose.Position.y)
|
||||
if (!item->ItemFlags[0] && !item->TriggerFlags && abs(item->Pose.Position.y - l->Pose.Position.y) < FALLINGBLOCK_HEIGHT_TOLERANCE)
|
||||
{
|
||||
if (!((item->Pose.Position.x ^ l->Pose.Position.x) & 0xFFFFFC00) && !((l->Pose.Position.z ^ item->Pose.Position.z) & 0xFFFFFC00))
|
||||
{
|
||||
|
|
|
@ -259,7 +259,7 @@ void WreckingBallControl(short itemNumber)
|
|||
item->Pose.Position.y += item->Animation.VerticalVelocity;
|
||||
if (item->Pose.Position.y < item2->Pose.Position.y + 1644)
|
||||
{
|
||||
StopSoundEffect(SFX_TR5_BASE_CLAW_WINCH_LOOP);
|
||||
StopSoundEffect(SFX_TR5_BASE_CLAW_WINCH_UP_LOOP);
|
||||
item->ItemFlags[0] = 1;
|
||||
item->Pose.Position.y = item2->Pose.Position.y + 1644;
|
||||
if (item->Animation.VerticalVelocity < -32)
|
||||
|
@ -277,7 +277,7 @@ void WreckingBallControl(short itemNumber)
|
|||
}
|
||||
else if (!item->ItemFlags[0])
|
||||
{
|
||||
SoundEffect(SFX_TR5_BASE_CLAW_WINCH_LOOP, &item->Pose);
|
||||
SoundEffect(SFX_TR5_BASE_CLAW_WINCH_UP_LOOP, &item->Pose);
|
||||
}
|
||||
}
|
||||
item2->Pose.Position.x = item->Pose.Position.x;
|
||||
|
|
|
@ -263,17 +263,15 @@ void KeyHoleCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll)
|
|||
}
|
||||
}
|
||||
|
||||
if (!((TrInput & IN_ACTION || g_Gui.GetInventoryItemChosen() != NO_ITEM) &&
|
||||
!BinocularRange &&
|
||||
bool actionReady = (TrInput & IN_ACTION || g_Gui.GetInventoryItemChosen() != NO_ITEM);
|
||||
|
||||
bool laraAvailable = !BinocularRange &&
|
||||
laraItem->Animation.ActiveState == LS_IDLE &&
|
||||
laraItem->Animation.AnimNumber == LA_STAND_IDLE) &&
|
||||
laraInfo->Control.HandStatus == HandStatus::Free &&
|
||||
(!laraInfo->Control.IsMoving || laraInfo->InteractedItem != itemNumber))
|
||||
{
|
||||
if (keyHoleItem->ObjectNumber < ID_KEY_HOLE6)
|
||||
ObjectCollision(itemNumber, laraItem, coll);
|
||||
}
|
||||
else
|
||||
laraItem->Animation.AnimNumber == LA_STAND_IDLE;
|
||||
|
||||
bool actionActive = laraInfo->Control.IsMoving && laraInfo->InteractedItem == itemNumber;
|
||||
|
||||
if (actionActive || (actionReady && laraAvailable))
|
||||
{
|
||||
if (TestLaraPosition(&KeyHoleBounds, keyHoleItem, laraItem))
|
||||
{
|
||||
|
@ -292,8 +290,13 @@ void KeyHoleCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll)
|
|||
|
||||
if (g_Gui.GetInventoryItemChosen() != keyHoleItem->ObjectNumber - (ID_KEY_HOLE1 - ID_KEY_ITEM1))
|
||||
return;
|
||||
|
||||
laraInfo->InteractedItem = itemNumber;
|
||||
}
|
||||
|
||||
if (laraInfo->InteractedItem != itemNumber)
|
||||
return;
|
||||
|
||||
if (MoveLaraPosition(&KeyHolePosition, keyHoleItem, laraItem))
|
||||
{
|
||||
if (keyHoleItem->ObjectNumber == ID_KEY_HOLE8)
|
||||
|
@ -319,8 +322,6 @@ void KeyHoleCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll)
|
|||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
laraInfo->InteractedItem = itemNumber;
|
||||
|
||||
g_Gui.SetInventoryItemChosen(NO_ITEM);
|
||||
return;
|
||||
|
@ -332,6 +333,11 @@ void KeyHoleCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll)
|
|||
laraInfo->Control.HandStatus = HandStatus::Free;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (keyHoleItem->ObjectNumber < ID_KEY_HOLE6)
|
||||
ObjectCollision(itemNumber, laraItem, coll);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -10,28 +10,29 @@
|
|||
#include "Specific/level.h"
|
||||
#include "Specific/setup.h"
|
||||
|
||||
BITE_INFO ApeBite = { 0, -19, 75, 15 };
|
||||
|
||||
#define ATTACK_DAMAGE 200
|
||||
|
||||
#define TOUCH (0xFF00)
|
||||
|
||||
#define RUN_TURN ANGLE(5.0f)
|
||||
|
||||
#define DISPLAY_ANGLE ANGLE(45.0f)
|
||||
|
||||
#define ATTACK_RANGE pow(430, 2)
|
||||
#define PANIC_RANGE pow(SECTOR(2), 2)
|
||||
|
||||
#define JUMP_CHANCE 0xa0
|
||||
#define WARNING_1_CHANCE (JUMP_CHANCE + 0xA0)
|
||||
#define WARNING_2_CHANCE (WARNING_1_CHANCE + 0xA0)
|
||||
#define RUNLEFT_CHANCE (WARNING_2_CHANCE + 0x110)
|
||||
|
||||
#define SHIFT 75
|
||||
|
||||
enum ApeState
|
||||
namespace TEN::Entities::TR1
|
||||
{
|
||||
BITE_INFO ApeBite = { 0, -19, 75, 15 };
|
||||
const std::vector<int> ApeAttackJoints = { 8, 9, 10, 11, 12, 13, 14, 15 };
|
||||
|
||||
constexpr auto APE_ATTACK_DAMAGE = 200;
|
||||
|
||||
#define RUN_TURN ANGLE(5.0f)
|
||||
|
||||
#define DISPLAY_ANGLE ANGLE(45.0f)
|
||||
|
||||
#define ATTACK_RANGE pow(430, 2)
|
||||
#define PANIC_RANGE pow(SECTOR(2), 2)
|
||||
|
||||
#define JUMP_CHANCE 0xa0
|
||||
#define WARNING_1_CHANCE (JUMP_CHANCE + 0xA0)
|
||||
#define WARNING_2_CHANCE (WARNING_1_CHANCE + 0xA0)
|
||||
#define RUNLEFT_CHANCE (WARNING_2_CHANCE + 0x110)
|
||||
|
||||
#define SHIFT 75
|
||||
|
||||
enum ApeState
|
||||
{
|
||||
APE_STATE_NONE = 0,
|
||||
APE_STATE_IDLE = 1,
|
||||
APE_STATE_WALK = 2,
|
||||
|
@ -44,25 +45,25 @@ enum ApeState
|
|||
APE_STATE_RUN_RIGHT = 9,
|
||||
APE_STATE_JUMP = 10,
|
||||
APE_STATE_VAULT = 11
|
||||
};
|
||||
};
|
||||
|
||||
// TODO
|
||||
enum ApeAnim
|
||||
{
|
||||
// TODO
|
||||
enum ApeAnim
|
||||
{
|
||||
APE_ANIM_DEATH = 7,
|
||||
|
||||
APE_ANIM_VAULT = 19,
|
||||
};
|
||||
};
|
||||
|
||||
enum ApeFlags
|
||||
{
|
||||
enum ApeFlags
|
||||
{
|
||||
APE_FLAG_ATTACK = 1,
|
||||
APE_FLAG_TURN_LEFT = 2,
|
||||
APE_FLAG_TURN_RIGHT = 4
|
||||
};
|
||||
};
|
||||
|
||||
void ApeVault(short itemNumber, short angle)
|
||||
{
|
||||
void ApeVault(short itemNumber, short angle)
|
||||
{
|
||||
auto* item = &g_Level.Items[itemNumber];
|
||||
auto* creature = GetCreatureInfo(item);
|
||||
|
||||
|
@ -134,10 +135,10 @@ void ApeVault(short itemNumber, short angle)
|
|||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ApeControl(short itemNumber)
|
||||
{
|
||||
void ApeControl(short itemNumber)
|
||||
{
|
||||
if (!CreatureActive(itemNumber))
|
||||
return;
|
||||
|
||||
|
@ -227,7 +228,7 @@ void ApeControl(short itemNumber)
|
|||
{
|
||||
item->Animation.TargetState = APE_STATE_IDLE;
|
||||
}
|
||||
else if (AI.ahead && item->TouchBits & TOUCH)
|
||||
else if (AI.ahead && item->TestBits(JointBitType::Touch, ApeAttackJoints))
|
||||
{
|
||||
item->Animation.RequiredState = APE_STATE_ATTACK;
|
||||
item->Animation.TargetState = APE_STATE_IDLE;
|
||||
|
@ -275,12 +276,13 @@ void ApeControl(short itemNumber)
|
|||
break;
|
||||
|
||||
case APE_STATE_ATTACK:
|
||||
if (!item->Animation.RequiredState && item->TouchBits & TOUCH)
|
||||
if (!item->Animation.RequiredState &&
|
||||
item->TestBits(JointBitType::Touch, ApeAttackJoints))
|
||||
{
|
||||
CreatureEffect(item, &ApeBite, DoBloodSplat);
|
||||
item->Animation.RequiredState = APE_STATE_IDLE;
|
||||
|
||||
LaraItem->HitPoints -= ATTACK_DAMAGE;
|
||||
LaraItem->HitPoints -= APE_ATTACK_DAMAGE;
|
||||
LaraItem->HitStatus = true;
|
||||
}
|
||||
|
||||
|
@ -294,4 +296,5 @@ void ApeControl(short itemNumber)
|
|||
ApeVault(itemNumber, angle);
|
||||
else
|
||||
CreatureAnimation(itemNumber, angle, 0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
void ApeControl(short itemNumber);
|
||||
namespace TEN::Entities::TR1
|
||||
{
|
||||
void ApeControl(short itemNumber);
|
||||
}
|
||||
|
|
|
@ -11,25 +11,27 @@
|
|||
#include "Specific/level.h"
|
||||
#include "Specific/setup.h"
|
||||
|
||||
BITE_INFO BearBite = { 0, 96, 335, 14 };
|
||||
|
||||
#define TOUCH 0x2406C
|
||||
#define ROAR_CHANCE 0x50
|
||||
#define REAR_CHANCE 0x300
|
||||
#define DROP_CHANCE 0x600
|
||||
#define REAR_RANGE pow(SECTOR(2), 2)
|
||||
#define ATTACK_RANGE pow(SECTOR(1), 2)
|
||||
#define PAT_RANGE pow(600, 2)
|
||||
#define RUN_TURN ANGLE(5.0f)
|
||||
#define WALK_TURN ANGLE(2.0f)
|
||||
#define EAT_RANGE pow(CLICK(3), 2)
|
||||
#define CHARGE_DAMAGE 3
|
||||
#define SLAM_DAMAGE 200
|
||||
#define ATTACK_DAMAGE 200
|
||||
#define PAT_DAMAGE 400
|
||||
|
||||
enum BearState
|
||||
namespace TEN::Entities::TR1
|
||||
{
|
||||
BITE_INFO BearBite = { 0, 96, 335, 14 };
|
||||
const std::vector<int> BearAttackJoints = { 2, 3, 5, 6, 14, 17 };
|
||||
|
||||
#define ROAR_CHANCE 0x50
|
||||
#define REAR_CHANCE 0x300
|
||||
#define DROP_CHANCE 0x600
|
||||
#define REAR_RANGE pow(SECTOR(2), 2)
|
||||
#define ATTACK_RANGE pow(SECTOR(1), 2)
|
||||
#define PAT_RANGE pow(600, 2)
|
||||
#define RUN_TURN ANGLE(5.0f)
|
||||
#define WALK_TURN ANGLE(2.0f)
|
||||
#define EAT_RANGE pow(CLICK(3), 2)
|
||||
#define CHARGE_DAMAGE 3
|
||||
#define SLAM_DAMAGE 200
|
||||
#define ATTACK_DAMAGE 200
|
||||
#define PAT_DAMAGE 400
|
||||
|
||||
enum BearState
|
||||
{
|
||||
BEAR_STATE_STROLL = 0,
|
||||
BEAR_STATE_IDLE = 1,
|
||||
BEAR_STATE_WALK = 2,
|
||||
|
@ -40,16 +42,16 @@ enum BearState
|
|||
BEAR_STATE_ATTACK_2 = 7,
|
||||
BEAR_STATE_CHOMP = 8,
|
||||
BEAR_STATE_DEATH = 9
|
||||
};
|
||||
};
|
||||
|
||||
// TODO
|
||||
enum BearAnim
|
||||
{
|
||||
// TODO
|
||||
enum BearAnim
|
||||
{
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
void BearControl(short itemNumber)
|
||||
{
|
||||
void BearControl(short itemNumber)
|
||||
{
|
||||
if (!CreatureActive(itemNumber))
|
||||
return;
|
||||
|
||||
|
@ -90,7 +92,7 @@ void BearControl(short itemNumber)
|
|||
}
|
||||
case BEAR_STATE_DEATH:
|
||||
{
|
||||
if (creature->Flags && item->TouchBits & TOUCH)
|
||||
if (creature->Flags && item->TestBits(JointBitType::Touch, BearAttackJoints))
|
||||
{
|
||||
creature->Flags = 0;
|
||||
|
||||
|
@ -142,7 +144,7 @@ void BearControl(short itemNumber)
|
|||
case BEAR_STATE_STROLL:
|
||||
creature->MaxTurn = WALK_TURN;
|
||||
|
||||
if (laraDead && item->TouchBits & TOUCH && AI.ahead)
|
||||
if (laraDead && item->TestBits(JointBitType::Touch, BearAttackJoints) && AI.ahead)
|
||||
item->Animation.TargetState = BEAR_STATE_IDLE;
|
||||
else if (creature->Mood != MoodType::Bored)
|
||||
{
|
||||
|
@ -162,7 +164,7 @@ void BearControl(short itemNumber)
|
|||
case BEAR_STATE_RUN:
|
||||
creature->MaxTurn = RUN_TURN;
|
||||
|
||||
if (item->TouchBits & TOUCH)
|
||||
if (item->TestBits(JointBitType::Touch, BearAttackJoints))
|
||||
{
|
||||
LaraItem->HitPoints -= CHARGE_DAMAGE;
|
||||
LaraItem->HitStatus = true;
|
||||
|
@ -206,7 +208,7 @@ void BearControl(short itemNumber)
|
|||
item->Animation.RequiredState = BEAR_STATE_STROLL;
|
||||
item->Animation.TargetState = BEAR_STATE_REAR;
|
||||
}
|
||||
else if (AI.ahead && (item->TouchBits & TOUCH))
|
||||
else if (AI.ahead && item->TestBits(JointBitType::Touch, BearAttackJoints))
|
||||
item->Animation.TargetState = BEAR_STATE_REAR;
|
||||
else if (creature->Mood == MoodType::Escape)
|
||||
{
|
||||
|
@ -227,7 +229,8 @@ void BearControl(short itemNumber)
|
|||
break;
|
||||
|
||||
case BEAR_STATE_ATTACK_2:
|
||||
if (!item->Animation.RequiredState && item->TouchBits & TOUCH)
|
||||
if (!item->Animation.RequiredState &&
|
||||
item->TestBits(JointBitType::Touch, BearAttackJoints))
|
||||
{
|
||||
item->Animation.RequiredState = BEAR_STATE_REAR;
|
||||
|
||||
|
@ -238,7 +241,8 @@ void BearControl(short itemNumber)
|
|||
break;
|
||||
|
||||
case BEAR_STATE_ATTACK_1:
|
||||
if (!item->Animation.RequiredState && (item->TouchBits & TOUCH))
|
||||
if (!item->Animation.RequiredState &&
|
||||
item->TestBits(JointBitType::Touch, BearAttackJoints))
|
||||
{
|
||||
CreatureEffect(item, &BearBite, DoBloodSplat);
|
||||
item->Animation.RequiredState = BEAR_STATE_IDLE;
|
||||
|
@ -253,4 +257,5 @@ void BearControl(short itemNumber)
|
|||
|
||||
CreatureJoint(item, 0, head);
|
||||
CreatureAnimation(itemNumber, angle, 0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
void BearControl(short itemNumber);
|
||||
namespace TEN::Entities::TR1
|
||||
{
|
||||
void BearControl(short itemNumber);
|
||||
}
|
||||
|
|
|
@ -12,24 +12,26 @@
|
|||
#include "Specific/level.h"
|
||||
#include "Specific/setup.h"
|
||||
|
||||
static BITE_INFO BigRatBite = { 0, -11, 108, 3 };
|
||||
|
||||
#define BIG_RAT_RUN_TURN ANGLE(6.0f)
|
||||
#define BIG_RAT_SWIM_TURN ANGLE(3.0f)
|
||||
|
||||
constexpr auto DEFAULT_SWIM_UPDOWN_SPEED = 32;
|
||||
constexpr auto BIG_RAT_TOUCH = 0x300018f;
|
||||
constexpr auto BIG_RAT_ALERT_RANGE = SQUARE(SECTOR(1) + CLICK(2));
|
||||
constexpr auto BIG_RAT_VISIBILITY_RANGE = SQUARE(SECTOR(5));
|
||||
constexpr auto BIG_RAT_BITE_RANGE = SQUARE(CLICK(1) + CLICK(1) / 3);
|
||||
constexpr auto BIG_RAT_CHARGE_RANGE = SQUARE(SECTOR(1) / 2);
|
||||
constexpr auto BIG_RAT_POSE_CHANCE = 0x100;
|
||||
constexpr auto BIG_RAT_WATER_BITE_RANGE = SQUARE(CLICK(1) + CLICK(1) / 6);
|
||||
constexpr auto BIG_RAT_BITE_DAMAGE = 20;
|
||||
constexpr auto BIG_RAT_CHARGE_DAMAGE = 25;
|
||||
|
||||
enum BigRatState
|
||||
namespace TEN::Entities::TR1
|
||||
{
|
||||
static BITE_INFO BigRatBite = { 0, -11, 108, 3 };
|
||||
const std::vector<int> BigRatAttackJoints = { 0, 1, 2, 3, 7, 8, 24, 25 };
|
||||
|
||||
#define BIG_RAT_RUN_TURN ANGLE(6.0f)
|
||||
#define BIG_RAT_SWIM_TURN ANGLE(3.0f)
|
||||
|
||||
constexpr auto DEFAULT_SWIM_UPDOWN_SPEED = 32;
|
||||
constexpr auto BIG_RAT_ALERT_RANGE = SQUARE(SECTOR(1) + CLICK(2));
|
||||
constexpr auto BIG_RAT_VISIBILITY_RANGE = SQUARE(SECTOR(5));
|
||||
constexpr auto BIG_RAT_BITE_RANGE = SQUARE(CLICK(1) + CLICK(1) / 3);
|
||||
constexpr auto BIG_RAT_CHARGE_RANGE = SQUARE(SECTOR(1) / 2);
|
||||
constexpr auto BIG_RAT_POSE_CHANCE = 0x100;
|
||||
constexpr auto BIG_RAT_WATER_BITE_RANGE = SQUARE(CLICK(1) + CLICK(1) / 6);
|
||||
constexpr auto BIG_RAT_BITE_DAMAGE = 20;
|
||||
constexpr auto BIG_RAT_CHARGE_DAMAGE = 25;
|
||||
|
||||
enum BigRatState
|
||||
{
|
||||
BIG_RAT_STATE_EMPTY = 0,
|
||||
BIG_RAT_STATE_IDLE = 1,
|
||||
BIG_RAT_STATE_CHARGE_ATTACK = 2,
|
||||
|
@ -40,10 +42,10 @@ enum BigRatState
|
|||
BIG_RAT_STATE_SWIM = 7,
|
||||
BIG_RAT_STATE_SWIM_ATTACK = 8,
|
||||
BIG_RAT_STATE_WATER_DEATH = 9
|
||||
};
|
||||
};
|
||||
|
||||
enum BigRatAnim
|
||||
{
|
||||
enum BigRatAnim
|
||||
{
|
||||
BIG_RAT_ANIM_EMPTY = 0,
|
||||
BIG_RAT_ANIM_STOP_TO_RUN = 1,
|
||||
BIG_RAT_ANIM_RUN = 2,
|
||||
|
@ -58,10 +60,10 @@ enum BigRatAnim
|
|||
BIG_RAT_ANIM_WATER_DEATH = 11,
|
||||
BIG_RAT_ANIM_RUN_TO_SWIM = 12,
|
||||
BIG_RAT_ANIM_SWIM_TO_RUN = 13
|
||||
};
|
||||
};
|
||||
|
||||
void InitialiseBigRat(short itemNumber)
|
||||
{
|
||||
void InitialiseBigRat(short itemNumber)
|
||||
{
|
||||
auto* item = &g_Level.Items[itemNumber];
|
||||
InitialiseCreature(itemNumber);
|
||||
|
||||
|
@ -79,10 +81,10 @@ void InitialiseBigRat(short itemNumber)
|
|||
item->Animation.ActiveState = BIG_RAT_STATE_IDLE;
|
||||
item->Animation.TargetState = BIG_RAT_STATE_IDLE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool RatIsInWater(ItemInfo* item)
|
||||
{
|
||||
static bool RatIsInWater(ItemInfo* item)
|
||||
{
|
||||
auto* creature = GetCreatureInfo(item);
|
||||
|
||||
EntityStoringInfo storingInfo;
|
||||
|
@ -108,10 +110,10 @@ static bool RatIsInWater(ItemInfo* item)
|
|||
creature->LOT.Fly = NO_FLYING;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BigRatControl(short itemNumber)
|
||||
{
|
||||
void BigRatControl(short itemNumber)
|
||||
{
|
||||
if (!CreatureActive(itemNumber))
|
||||
return;
|
||||
|
||||
|
@ -196,7 +198,7 @@ void BigRatControl(short itemNumber)
|
|||
break;
|
||||
}
|
||||
|
||||
if (AI.ahead && (item->TouchBits & BIG_RAT_TOUCH))
|
||||
if (AI.ahead && item->TestBits(JointBitType::Touch, BigRatAttackJoints))
|
||||
item->Animation.TargetState = BIG_RAT_STATE_IDLE;
|
||||
else if (AI.bite && AI.distance < BIG_RAT_CHARGE_RANGE)
|
||||
item->Animation.TargetState = BIG_RAT_STATE_CHARGE_ATTACK;
|
||||
|
@ -209,7 +211,8 @@ void BigRatControl(short itemNumber)
|
|||
break;
|
||||
|
||||
case BIG_RAT_STATE_BITE_ATTACK:
|
||||
if (!item->Animation.RequiredState && AI.ahead && (item->TouchBits & BIG_RAT_TOUCH))
|
||||
if (!item->Animation.RequiredState && AI.ahead &&
|
||||
item->TestBits(JointBitType::Touch, BigRatAttackJoints))
|
||||
{
|
||||
CreatureEffect(item, &BigRatBite, DoBloodSplat);
|
||||
item->Animation.RequiredState = BIG_RAT_STATE_IDLE;
|
||||
|
@ -221,7 +224,8 @@ void BigRatControl(short itemNumber)
|
|||
break;
|
||||
|
||||
case BIG_RAT_STATE_CHARGE_ATTACK:
|
||||
if (!item->Animation.RequiredState && AI.ahead && (item->TouchBits & BIG_RAT_TOUCH))
|
||||
if (!item->Animation.RequiredState && AI.ahead &&
|
||||
item->TestBits(JointBitType::Touch, BigRatAttackJoints))
|
||||
{
|
||||
CreatureEffect(item, &BigRatBite, DoBloodSplat);
|
||||
item->Animation.RequiredState = BIG_RAT_STATE_RUN;
|
||||
|
@ -248,13 +252,14 @@ void BigRatControl(short itemNumber)
|
|||
break;
|
||||
}
|
||||
|
||||
if (AI.ahead && item->TouchBits & BIG_RAT_TOUCH)
|
||||
if (AI.ahead && item->TestBits(JointBitType::Touch, BigRatAttackJoints))
|
||||
item->Animation.TargetState = BIG_RAT_STATE_SWIM_ATTACK;
|
||||
|
||||
break;
|
||||
|
||||
case BIG_RAT_STATE_SWIM_ATTACK:
|
||||
if (!item->Animation.RequiredState && AI.ahead && item->TouchBits & BIG_RAT_TOUCH)
|
||||
if (!item->Animation.RequiredState && AI.ahead &&
|
||||
item->TestBits(JointBitType::Touch, BigRatAttackJoints))
|
||||
{
|
||||
CreatureEffect(item, &BigRatBite, DoBloodSplat);
|
||||
|
||||
|
@ -278,4 +283,5 @@ void BigRatControl(short itemNumber)
|
|||
}
|
||||
else
|
||||
item->Pose.Position.y = item->Floor;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
void InitialiseBigRat(short itemNumber);
|
||||
void BigRatControl(short itemNumber);
|
||||
namespace TEN::Entities::TR1
|
||||
{
|
||||
void InitialiseBigRat(short itemNumber);
|
||||
void BigRatControl(short itemNumber);
|
||||
}
|
||||
|
|
|
@ -16,19 +16,21 @@
|
|||
#include "Specific/level.h"
|
||||
#include "Specific/setup.h"
|
||||
|
||||
BITE_INFO CentaurRocketBite = { 11, 415, 41, 13 };
|
||||
BITE_INFO CentaurRearBite = { 50, 30, 0, 5 };
|
||||
namespace TEN::Entities::TR1
|
||||
{
|
||||
BITE_INFO CentaurRocketBite = { 11, 415, 41, 13 };
|
||||
BITE_INFO CentaurRearBite = { 50, 30, 0, 5 };
|
||||
std::vector<int> CentaurAttackJoints = { 0, 3, 4, 7, 8, 16, 17 };
|
||||
|
||||
#define BOMB_SPEED 256
|
||||
#define CENTAUR_TOUCH 0x30199
|
||||
#define CENTAUR_TURN ANGLE(4.0f)
|
||||
#define CENTAUR_REAR_CHANCE 0x60
|
||||
#define CENTAUR_REAR_RANGE pow(SECTOR(1.5f), 2)
|
||||
#define FLYER_PART_DAMAGE 100
|
||||
#define CENTAUR_REAR_DAMAGE 200
|
||||
|
||||
enum CentaurState
|
||||
{
|
||||
enum CentaurState
|
||||
{
|
||||
CENTAUR_STATE_NONE = 0,
|
||||
CENTAUR_STATE_IDLE = 1,
|
||||
CENTAUR_STATE_SHOOT = 2,
|
||||
|
@ -36,20 +38,20 @@ enum CentaurState
|
|||
CENTAUR_STATE_AIM = 4,
|
||||
CENTAUR_STATE_DEATH = 5,
|
||||
CENTAUR_STATE_WARNING = 6
|
||||
};
|
||||
};
|
||||
|
||||
// TODO
|
||||
enum CentaurAnim
|
||||
{
|
||||
// TODO
|
||||
enum CentaurAnim
|
||||
{
|
||||
CENTAUR_ANIM_DEATH = 8,
|
||||
};
|
||||
};
|
||||
|
||||
void ControlCentaurBomb(short itemNumber)
|
||||
{
|
||||
void ControlCentaurBomb(short itemNumber)
|
||||
{
|
||||
auto* item = &g_Level.Items[itemNumber];
|
||||
|
||||
bool aboveWater = false;
|
||||
Vector3Int oldPos = { item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z };
|
||||
auto oldPos = item->Pose.Position;
|
||||
|
||||
item->Pose.Orientation.z += ANGLE(35.0f);
|
||||
if (!TestEnvironment(ENV_FLAG_WATER, item->RoomNumber))
|
||||
|
@ -79,9 +81,7 @@ void ControlCentaurBomb(short itemNumber)
|
|||
}
|
||||
}
|
||||
|
||||
item->Pose.Position.x += item->Animation.Velocity * phd_cos(item->Pose.Orientation.x) * phd_sin(item->Pose.Orientation.y);
|
||||
item->Pose.Position.y += item->Animation.Velocity * phd_sin(-item->Pose.Orientation.x);
|
||||
item->Pose.Position.z += item->Animation.Velocity * phd_cos(item->Pose.Orientation.x) * phd_cos(item->Pose.Orientation.y);
|
||||
TranslateItem(item, item->Pose.Orientation, item->Animation.Velocity);
|
||||
|
||||
auto probe = GetCollision(item);
|
||||
|
||||
|
@ -137,10 +137,10 @@ void ControlCentaurBomb(short itemNumber)
|
|||
|
||||
} while (currentItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void RocketGun(ItemInfo* centaurItem)
|
||||
{
|
||||
static void RocketGun(ItemInfo* centaurItem)
|
||||
{
|
||||
short itemNumber;
|
||||
itemNumber = CreateItem();
|
||||
|
||||
|
@ -168,10 +168,10 @@ static void RocketGun(ItemInfo* centaurItem)
|
|||
|
||||
AddActiveItem(itemNumber);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CentaurControl(short itemNumber)
|
||||
{
|
||||
void CentaurControl(short itemNumber)
|
||||
{
|
||||
auto* item = &g_Level.Items[itemNumber];
|
||||
auto* creature = GetCreatureInfo(item);
|
||||
|
||||
|
@ -256,7 +256,8 @@ void CentaurControl(short itemNumber)
|
|||
break;
|
||||
|
||||
case CENTAUR_STATE_WARNING:
|
||||
if (!item->Animation.RequiredState && item->TouchBits & CENTAUR_TOUCH)
|
||||
if (!item->Animation.RequiredState &&
|
||||
item->TestBits(JointBitType::Touch, CentaurAttackJoints))
|
||||
{
|
||||
CreatureEffect(item, &CentaurRearBite, DoBloodSplat);
|
||||
item->Animation.RequiredState = CENTAUR_STATE_IDLE;
|
||||
|
@ -275,8 +276,9 @@ void CentaurControl(short itemNumber)
|
|||
if (item->Status == ITEM_DEACTIVATED)
|
||||
{
|
||||
SoundEffect(SFX_TR1_ATLANTEAN_DEATH, &item->Pose);
|
||||
ExplodingDeath(itemNumber, 0xffffffff, FLYER_PART_DAMAGE);
|
||||
ExplodingDeath(itemNumber, ALL_JOINT_BITS, FLYER_PART_DAMAGE);
|
||||
KillItem(itemNumber);
|
||||
item->Status = ITEM_DEACTIVATED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
void CentaurControl(short itemNumber);
|
||||
void ControlCentaurBomb(short itemNumber);
|
||||
namespace TEN::Entities::TR1
|
||||
{
|
||||
void CentaurControl(short itemNumber);
|
||||
void ControlCentaurBomb(short itemNumber);
|
||||
}
|
||||
|
|
|
@ -14,14 +14,16 @@
|
|||
// - Bacon Lara cannot be targeted.
|
||||
// - Bacon Lara cannot move like Lara.
|
||||
|
||||
// Original:
|
||||
void InitialiseDoppelganger(short itemNumber)
|
||||
namespace TEN::Entities::TR1
|
||||
{
|
||||
// Original:
|
||||
void InitialiseDoppelganger(short itemNumber)
|
||||
{
|
||||
ClearItem(itemNumber);
|
||||
}
|
||||
}
|
||||
|
||||
ItemInfo* FindReference(ItemInfo* item, short objectNumber)
|
||||
{
|
||||
ItemInfo* FindReference(ItemInfo* item, short objectNumber)
|
||||
{
|
||||
bool found = false;
|
||||
int itemNumber;
|
||||
for (int i = 0; i < g_Level.NumItems; i++)
|
||||
|
@ -38,20 +40,20 @@ ItemInfo* FindReference(ItemInfo* item, short objectNumber)
|
|||
itemNumber = NO_ITEM;
|
||||
|
||||
return (itemNumber == NO_ITEM ? NULL : &g_Level.Items[itemNumber]);
|
||||
}
|
||||
}
|
||||
|
||||
static short GetWeaponDamage(LaraWeaponType weaponType)
|
||||
{
|
||||
static short GetWeaponDamage(LaraWeaponType weaponType)
|
||||
{
|
||||
return short(Weapons[(int)weaponType].Damage) * 25;
|
||||
}
|
||||
}
|
||||
|
||||
void DoppelgangerControl(short itemNumber)
|
||||
{
|
||||
void DoppelgangerControl(short itemNumber)
|
||||
{
|
||||
auto* item = &g_Level.Items[itemNumber];
|
||||
|
||||
if (item->HitPoints < 1000)
|
||||
if (item->HitPoints < LARA_HEALTH_MAX)
|
||||
{
|
||||
item->HitPoints = 1000;
|
||||
item->HitPoints = LARA_HEALTH_MAX;
|
||||
LaraItem->HitPoints -= GetWeaponDamage(Lara.Control.Weapon.GunType);
|
||||
}
|
||||
|
||||
|
@ -118,11 +120,11 @@ void DoppelgangerControl(short itemNumber)
|
|||
item->Animation.RequiredState = LS_DEATH;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: DrawLara not exist ! use Renderer11.cpp DrawLara instead or create DrawLara() function with old behaviour.
|
||||
void DrawEvilLara(ItemInfo* item)
|
||||
{
|
||||
// TODO: DrawLara not exist ! use Renderer11.cpp DrawLara instead or create DrawLara() function with old behaviour.
|
||||
void DrawEvilLara(ItemInfo* item)
|
||||
{
|
||||
/*
|
||||
short* meshstore[15];
|
||||
short** meshpp;
|
||||
|
@ -139,4 +141,5 @@ void DrawEvilLara(ItemInfo* item)
|
|||
|
||||
for (i = 0; i < 15; i++)
|
||||
Lara.meshPtrs[i] = meshstore[i];*/
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
void InitialiseDoppelganger(short itemNumber);
|
||||
void DoppelgangerControl(short itemNumber);
|
||||
namespace TEN::Entities::TR1
|
||||
{
|
||||
void InitialiseDoppelganger(short itemNumber);
|
||||
void DoppelgangerControl(short itemNumber);
|
||||
}
|
||||
|
|
|
@ -14,22 +14,25 @@
|
|||
#include "Specific/level.h"
|
||||
#include "Specific/setup.h"
|
||||
|
||||
#define MUTANT_NEED_TURN ANGLE(45.0f)
|
||||
#define MUTANT_TURN ANGLE(3.0f)
|
||||
#define MUTANT_ATTACK_RANGE pow(2600, 2)
|
||||
#define MUTANT_CLOSE_RANGE pow(2250, 2)
|
||||
#define MUTANT_ATTACK_1_CHANCE 11000
|
||||
#define MUTANT_ATTACK_2_CHANCE 22000
|
||||
#define MUTANT_TLEFT 0x7ff0
|
||||
#define MUTANT_TRIGHT 0x3ff8000
|
||||
#define MUTANT_TOUCH (MUTANT_TLEFT | MUTANT_TRIGHT)
|
||||
#define MUTANT_PART_DAMAGE 250
|
||||
#define MUTANT_ATTACK_DAMAGE 500
|
||||
#define MUTANT_TOUCH_DAMAGE 5
|
||||
#define LARA_GIANT_MUTANT_DEATH 6
|
||||
|
||||
enum GiantMutantState
|
||||
namespace TEN::Entities::TR1
|
||||
{
|
||||
const std::vector<int> MutantAttackJoints = { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 };
|
||||
const std::vector<int> MutantAttackLeftJoints = { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 };
|
||||
const std::vector<int> MutantAttackRightJoints = { 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 };
|
||||
|
||||
#define MUTANT_NEED_TURN ANGLE(45.0f)
|
||||
#define MUTANT_TURN ANGLE(3.0f)
|
||||
#define MUTANT_ATTACK_RANGE pow(2600, 2)
|
||||
#define MUTANT_CLOSE_RANGE pow(2250, 2)
|
||||
#define MUTANT_ATTACK_1_CHANCE 11000
|
||||
#define MUTANT_ATTACK_2_CHANCE 22000
|
||||
#define MUTANT_PART_DAMAGE 250
|
||||
#define MUTANT_ATTACK_DAMAGE 500
|
||||
#define MUTANT_TOUCH_DAMAGE 5
|
||||
#define LARA_GIANT_MUTANT_DEATH 6
|
||||
|
||||
enum GiantMutantState
|
||||
{
|
||||
MUTANT_STATE_NONE = 0,
|
||||
MUTANT_STATE_IDLE = 1,
|
||||
MUTANT_STATE_TURN_LEFT = 2,
|
||||
|
@ -42,16 +45,16 @@ enum GiantMutantState
|
|||
MUTANT_STATE_FALL = 9,
|
||||
MUTANT_STATE_DEATH = 10,
|
||||
MUTANT_STATE_KILL = 11
|
||||
};
|
||||
};
|
||||
|
||||
// TODO
|
||||
enum GianMutantAnim
|
||||
{
|
||||
// TODO
|
||||
enum GianMutantAnim
|
||||
{
|
||||
MUTANT_ANIM_DEATH = 13,
|
||||
};
|
||||
};
|
||||
|
||||
void GiantMutantControl(short itemNumber)
|
||||
{
|
||||
void GiantMutantControl(short itemNumber)
|
||||
{
|
||||
if (!CreatureActive(itemNumber))
|
||||
return;
|
||||
|
||||
|
@ -169,7 +172,7 @@ void GiantMutantControl(short itemNumber)
|
|||
break;
|
||||
|
||||
case MUTANT_STATE_ATTACK_1:
|
||||
if (!creature->Flags && item->TouchBits & MUTANT_TRIGHT)
|
||||
if (!creature->Flags && item->TestBits(JointBitType::Touch, MutantAttackRightJoints))
|
||||
{
|
||||
creature->Flags = 1;
|
||||
|
||||
|
@ -180,7 +183,7 @@ void GiantMutantControl(short itemNumber)
|
|||
break;
|
||||
|
||||
case MUTANT_STATE_ATTACK_2:
|
||||
if (!creature->Flags && item->TouchBits & MUTANT_TOUCH)
|
||||
if (!creature->Flags && item->TestBits(JointBitType::Touch, MutantAttackJoints))
|
||||
{
|
||||
creature->Flags = 1;
|
||||
|
||||
|
@ -191,13 +194,13 @@ void GiantMutantControl(short itemNumber)
|
|||
break;
|
||||
|
||||
case MUTANT_STATE_ATTACK_3:
|
||||
if (item->TouchBits & MUTANT_TRIGHT || LaraItem->HitPoints <= 0)
|
||||
if (item->TestBits(JointBitType::Touch, MutantAttackRightJoints) || LaraItem->HitPoints <= 0)
|
||||
{
|
||||
item->Animation.TargetState = MUTANT_STATE_KILL;
|
||||
Camera.targetDistance = SECTOR(2);
|
||||
Camera.flags = CF_FOLLOW_CENTER;
|
||||
|
||||
LaraItem->Animation.AnimNumber = Objects[ID_LARA_EXTRA_ANIMS].animIndex+LARA_GIANT_MUTANT_DEATH;
|
||||
LaraItem->Animation.AnimNumber = Objects[ID_LARA_EXTRA_ANIMS].animIndex + LARA_GIANT_MUTANT_DEATH;
|
||||
LaraItem->Animation.FrameNumber = g_Level.Anims[LaraItem->Animation.AnimNumber].frameBase;
|
||||
LaraItem->Animation.ActiveState = LaraItem->Animation.TargetState = 46;
|
||||
LaraItem->RoomNumber = item->RoomNumber;
|
||||
|
@ -242,11 +245,12 @@ void GiantMutantControl(short itemNumber)
|
|||
if (item->Status == ITEM_DEACTIVATED)
|
||||
{
|
||||
SoundEffect(SFX_TR1_ATLANTEAN_DEATH, &item->Pose);
|
||||
ExplodingDeath(itemNumber, UINT_MAX, MUTANT_PART_DAMAGE);
|
||||
ExplodingDeath(itemNumber, ALL_JOINT_BITS, MUTANT_PART_DAMAGE);
|
||||
|
||||
TestTriggers(item, true);
|
||||
|
||||
KillItem(itemNumber);
|
||||
item->Status = ITEM_DEACTIVATED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
void GiantMutantControl(short itemNumber);
|
||||
namespace TEN::Entities::TR1
|
||||
{
|
||||
void GiantMutantControl(short itemNumber);
|
||||
}
|
||||
|
|
|
@ -12,10 +12,12 @@
|
|||
#include "Specific/level.h"
|
||||
#include "Specific/trmath.h"
|
||||
|
||||
BITE_INFO NatlaGunBite = { 5, 220, 7, 4 };
|
||||
|
||||
enum NatlaState
|
||||
namespace TEN::Entities::TR1
|
||||
{
|
||||
BITE_INFO NatlaGunBite = { 5, 220, 7, 4 };
|
||||
|
||||
enum NatlaState
|
||||
{
|
||||
NATLA_STATE_NONE,
|
||||
NATLA_STATE_IDLE,
|
||||
NATLA_STATE_FLY,
|
||||
|
@ -26,7 +28,7 @@ enum NatlaState
|
|||
NATLA_STATE_FALL,
|
||||
NATLA_STATE_STAND,
|
||||
NATLA_STATE_DEATH
|
||||
};
|
||||
};
|
||||
|
||||
#define NATLA_NEAR_DEATH 200
|
||||
#define NATLA_FLYMODE 0x8000
|
||||
|
@ -35,11 +37,11 @@ enum NatlaState
|
|||
#define NATLA_FLY_TURN ANGLE(5.0f)
|
||||
#define NATLA_RUN_TURN ANGLE(6.0f)
|
||||
#define NATLA_LAND_CHANCE 0x100
|
||||
#define NATLA_DEATH_TIME (30 * 16)
|
||||
#define NATLA_DEATH_TIME (FPS * 16)
|
||||
#define NATLA_SHOT_DAMAGE 100
|
||||
|
||||
void NatlaControl(short itemNumber)
|
||||
{
|
||||
void NatlaControl(short itemNumber)
|
||||
{
|
||||
if (!CreatureActive(itemNumber))
|
||||
return;
|
||||
|
||||
|
@ -73,7 +75,7 @@ void NatlaControl(short itemNumber)
|
|||
CreatureMood(item, &AI, VIOLENT);
|
||||
|
||||
angle = CreatureTurn(item, NATLA_RUN_TURN);
|
||||
shoot = (AI.angle > -NATLA_FIRE_ARC && AI.angle < NATLA_FIRE_ARC && Targetable(item, &AI));
|
||||
shoot = (AI.angle > -NATLA_FIRE_ARC && AI.angle < NATLA_FIRE_ARC&& Targetable(item, &AI));
|
||||
|
||||
if (facing)
|
||||
{
|
||||
|
@ -173,7 +175,7 @@ void NatlaControl(short itemNumber)
|
|||
creature->LOT.Fly = NO_FLYING;
|
||||
CreatureAIInfo(item, &AI);
|
||||
|
||||
shoot = (AI.angle > -NATLA_FIRE_ARC && AI.angle < NATLA_FIRE_ARC && Targetable(item, &AI));
|
||||
shoot = (AI.angle > -NATLA_FIRE_ARC && AI.angle < NATLA_FIRE_ARC&& Targetable(item, &AI));
|
||||
|
||||
if (item->Animation.ActiveState == NATLA_STATE_FLY && (creature->Flags & NATLA_FLYMODE))
|
||||
{
|
||||
|
@ -293,4 +295,5 @@ void NatlaControl(short itemNumber)
|
|||
item->Pose.Orientation.y -= facing;
|
||||
CreatureAnimation(itemNumber, angle, tilt);
|
||||
item->Pose.Orientation.y += facing;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
void NatlaControl(short itemNumber);
|
||||
namespace TEN::Entities::TR1
|
||||
{
|
||||
void NatlaControl(short itemNumber);
|
||||
}
|
||||
|
|
|
@ -11,10 +11,29 @@
|
|||
#include "Specific/level.h"
|
||||
#include "Specific/setup.h"
|
||||
|
||||
BITE_INFO WolfBite = { 0, -14, 174, 6 };
|
||||
|
||||
enum WolfState
|
||||
namespace TEN::Entities::TR1
|
||||
{
|
||||
BITE_INFO WolfBite = { 0, -14, 174, 6 };
|
||||
const std::vector<int> WolfAttackJoints = { 0, 1, 2, 3, 6, 8, 9, 10, 12, 13, 14 };
|
||||
|
||||
#define SLEEP_FRAME 96
|
||||
|
||||
#define ATTACK_RANGE pow(SECTOR(1.5f), 2)
|
||||
#define STALK_RANGE pow(SECTOR(2), 2)
|
||||
|
||||
#define BITE_DAMAGE 100
|
||||
#define LUNGE_DAMAGE 50
|
||||
|
||||
#define WAKE_CHANCE 0x20
|
||||
#define SLEEP_CHANCE 0x20
|
||||
#define HOWL_CHANCE 0x180
|
||||
|
||||
#define WALK_TURN ANGLE(2.0f)
|
||||
#define RUN_TURN ANGLE(5.0f)
|
||||
#define STALK_TURN ANGLE(2.0f)
|
||||
|
||||
enum WolfState
|
||||
{
|
||||
WOLF_STATE_NONE = 0,
|
||||
WOLF_STATE_IDLE = 1,
|
||||
WOLF_STATE_WALK = 2,
|
||||
|
@ -28,42 +47,24 @@ enum WolfState
|
|||
WOLF_STATE_FAST_TURN = 10,
|
||||
WOLF_STATE_DEATH = 11,
|
||||
WOLF_STATE_BITE = 12
|
||||
};
|
||||
};
|
||||
|
||||
// TODO
|
||||
enum WolfAnim
|
||||
{
|
||||
// TODO
|
||||
enum WolfAnim
|
||||
{
|
||||
WOLF_ANIM_DEATH = 20,
|
||||
};
|
||||
};
|
||||
|
||||
#define TOUCH 0x774f
|
||||
|
||||
#define SLEEP_FRAME 96
|
||||
|
||||
#define ATTACK_RANGE pow(SECTOR(1.5f), 2)
|
||||
#define STALK_RANGE pow(SECTOR(2), 2)
|
||||
|
||||
#define BITE_DAMAGE 100
|
||||
#define LUNGE_DAMAGE 50
|
||||
|
||||
#define WAKE_CHANCE 0x20
|
||||
#define SLEEP_CHANCE 0x20
|
||||
#define HOWL_CHANCE 0x180
|
||||
|
||||
#define WALK_TURN ANGLE(2.0f)
|
||||
#define RUN_TURN ANGLE(5.0f)
|
||||
#define STALK_TURN ANGLE(2.0f)
|
||||
|
||||
void InitialiseWolf(short itemNumber)
|
||||
{
|
||||
void InitialiseWolf(short itemNumber)
|
||||
{
|
||||
auto* item = &g_Level.Items[itemNumber];
|
||||
|
||||
ClearItem(itemNumber);
|
||||
item->Animation.FrameNumber = SLEEP_FRAME;
|
||||
}
|
||||
}
|
||||
|
||||
void WolfControl(short itemNumber)
|
||||
{
|
||||
void WolfControl(short itemNumber)
|
||||
{
|
||||
if (!CreatureActive(itemNumber))
|
||||
return;
|
||||
|
||||
|
@ -211,7 +212,7 @@ void WolfControl(short itemNumber)
|
|||
case WOLF_STATE_ATTACK:
|
||||
tilt = angle;
|
||||
|
||||
if (!item->Animation.RequiredState && item->TouchBits & TOUCH)
|
||||
if (!item->Animation.RequiredState && item->TestBits(JointBitType::Touch, WolfAttackJoints))
|
||||
{
|
||||
CreatureEffect(item, &WolfBite, DoBloodSplat);
|
||||
LaraItem->HitPoints -= LUNGE_DAMAGE;
|
||||
|
@ -223,8 +224,8 @@ void WolfControl(short itemNumber)
|
|||
break;
|
||||
|
||||
case WOLF_STATE_BITE:
|
||||
if (!item->Animation.RequiredState &&
|
||||
item->TouchBits & TOUCH && AI.ahead)
|
||||
if (AI.ahead && !item->Animation.RequiredState &&
|
||||
item->TestBits(JointBitType::Touch, WolfAttackJoints))
|
||||
{
|
||||
CreatureEffect(item, &WolfBite, DoBloodSplat);
|
||||
LaraItem->HitPoints -= BITE_DAMAGE;
|
||||
|
@ -239,4 +240,5 @@ void WolfControl(short itemNumber)
|
|||
CreatureTilt(item, tilt);
|
||||
CreatureJoint(item, 0, head);
|
||||
CreatureAnimation(itemNumber, angle, tilt);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
void InitialiseWolf(short itemNumber);
|
||||
void WolfControl(short itemNumber);
|
||||
namespace TEN::Entities::TR1
|
||||
{
|
||||
void InitialiseWolf(short itemNumber);
|
||||
void WolfControl(short itemNumber);
|
||||
}
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
#include "Objects/TR1/Entity/tr1_centaur.h"
|
||||
#include "Objects/Utils/object_helper.h"
|
||||
|
||||
using namespace TEN::Entities::TR1;
|
||||
|
||||
static void StartEntity(ObjectInfo* obj)
|
||||
{
|
||||
obj = &Objects[ID_WOLF];
|
||||
|
|
|
@ -558,7 +558,7 @@ void BartoliControl(short itemNumber)
|
|||
frontItem = (short)back->Data;
|
||||
front = &g_Level.Items[frontItem];
|
||||
|
||||
front->TouchBits = back->TouchBits = 0;
|
||||
front->TouchBits = back->TouchBits = NO_JOINT_BITS;
|
||||
EnableBaddyAI(frontItem, 1);
|
||||
AddActiveItem(frontItem);
|
||||
AddActiveItem(backItem);
|
||||
|
|
|
@ -208,21 +208,21 @@ void SkidooManControl(short riderItemNumber)
|
|||
|
||||
if (creatureInfo->Flags)
|
||||
{
|
||||
SoundEffect(SFX_TR4_BAD_TROOP_UZI, &item->Pose);
|
||||
SoundEffect(SFX_TR4_BADDY_UZI, &item->Pose);
|
||||
creatureInfo->Flags--;
|
||||
}
|
||||
}
|
||||
|
||||
if (item->Animation.ActiveState == SMAN_STATE_WAIT)
|
||||
{
|
||||
SoundEffect(SFX_TR2_SNOWMOBILE_IDLE, &item->Pose);
|
||||
SoundEffect(SFX_TR2_VEHICLE_SNOWMOBILE_IDLE, &item->Pose);
|
||||
creatureInfo->JointRotation[0] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
creatureInfo->JointRotation[0] = (creatureInfo->JointRotation[0] == 1) ? 2 : 1;
|
||||
DoSnowEffect(item);
|
||||
SoundEffect(SFX_TR2_SNOWMOBILE_IDLE, &item->Pose, SoundEnvironment::Land, 0.5f + item->Animation.Velocity / 100.0f); // SKIDOO_MAX_VELOCITY. TODO: Check actual sound!
|
||||
SoundEffect(SFX_TR2_VEHICLE_SNOWMOBILE_IDLE, &item->Pose, SoundEnvironment::Land, 0.5f + item->Animation.Velocity / 100.0f); // SKIDOO_MAX_VELOCITY. TODO: Check actual sound!
|
||||
}
|
||||
|
||||
CreatureAnimation(itemNumber, angle, 0);
|
||||
|
|
|
@ -64,7 +64,7 @@ void SmallSpiderControl(short itemNumber)
|
|||
{
|
||||
if (item->Animation.ActiveState != 7)
|
||||
{
|
||||
ExplodingDeath(itemNumber, -1, 256);
|
||||
ExplodingDeath(itemNumber, ALL_JOINT_BITS, 256);
|
||||
DisableEntityAI(itemNumber);
|
||||
item->Animation.ActiveState = 7;
|
||||
KillItem(itemNumber);
|
||||
|
|
|
@ -56,7 +56,7 @@ void SwordGuardianControl(short itemNumber)
|
|||
SoundEffect(SFX_TR4_EXPLOSION2, &LaraItem->Pose);
|
||||
//item->meshBits = 0xFFFFFFFF;
|
||||
//item->objectNumber = ID_SAS;
|
||||
ExplodingDeath(itemNumber, -1, 256);
|
||||
ExplodingDeath(itemNumber, ALL_JOINT_BITS, 256);
|
||||
//item->objectNumber = ID_SWAT;
|
||||
DisableEntityAI(itemNumber);
|
||||
KillItem(itemNumber);
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include "Objects/TR2/Entity/tr2_worker_flamethrower.h"
|
||||
|
||||
#include "Game/animation.h"
|
||||
#include "Game/camera.h"
|
||||
#include "Game/control/box.h"
|
||||
#include "Game/control/control.h"
|
||||
#include "Game/effects/effects.h"
|
||||
|
@ -16,6 +17,7 @@
|
|||
#include "Specific/trmath.h"
|
||||
|
||||
BITE_INFO WorkerFlamethrowerBite = { 0, 250, 32, 9 };
|
||||
Vector3Int WorkerFlamethrowerOffset = { 0, 140, 0 };
|
||||
|
||||
// TODO
|
||||
enum WorkerFlamethrowerState
|
||||
|
@ -96,10 +98,13 @@ void WorkerFlamethrower(short itemNumber)
|
|||
if (item->Animation.ActiveState != 5 && item->Animation.ActiveState != 6)
|
||||
{
|
||||
TriggerDynamicLight(pos.x, pos.y, pos.z, (GetRandomControl() & 4) + 10, (GetRandomControl() & 7) + 128, (GetRandomControl() & 7) + 64, GetRandomControl() & 7);
|
||||
AddFire(pos.x, pos.y, pos.z, 0, item->RoomNumber, 0);
|
||||
TriggerPilotFlame(itemNumber, WorkerFlamethrowerBite.meshNum);
|
||||
}
|
||||
else
|
||||
{
|
||||
TriggerDynamicLight(pos.x, pos.y, pos.z, (GetRandomControl() & 4) + 14, (GetRandomControl() & 7) + 128, (GetRandomControl() & 7) + 64, GetRandomControl() & 7);
|
||||
ThrowFire(itemNumber, WorkerFlamethrowerBite.meshNum, WorkerFlamethrowerOffset, WorkerFlamethrowerOffset);
|
||||
}
|
||||
|
||||
AI_INFO AI;
|
||||
CreatureAIInfo(item, &AI);
|
||||
|
|
|
@ -32,12 +32,12 @@
|
|||
#define BOAT_SLIP 10
|
||||
#define BOAT_SIDE_SLIP 30
|
||||
#define BOAT_FRONT 750
|
||||
#define BOAT_BACK -700
|
||||
#define BOAT_SIDE 300
|
||||
#define BOAT_RADIUS 500
|
||||
#define BOAT_SNOW 500
|
||||
#define BOAT_MAX_HEIGHT CLICK(1)
|
||||
#define DISMOUNT_DISTANCE SECTOR(1)
|
||||
#define BOAT_WAKE 700
|
||||
#define BOAT_SOUND_CEILING SECTOR(5)
|
||||
#define BOAT_TIP (BOAT_FRONT + 250)
|
||||
|
||||
|
@ -99,83 +99,6 @@ void InitialiseSpeedBoat(short itemNumber)
|
|||
sBoat->Pitch = 0;
|
||||
}
|
||||
|
||||
void DoBoatWakeEffect(ItemInfo* sBoatItem)
|
||||
{
|
||||
//SetupRipple(sBoatItem->Pose.Position.x, sBoatItem->Pose.Position.y, sBoatItem->Pose.Position.z, 512, RIPPLE_FLAG_RAND_POS, Objects[1368].meshIndex, TO_RAD(sBoatItem->Pose.Orientation.y));
|
||||
TEN::Effects::TriggerSpeedboatFoam(sBoatItem);
|
||||
|
||||
// OLD WAKE EFFECT
|
||||
/*int c = phd_cos(boat->pos.Orientation.y);
|
||||
int s = phd_sin(boat->pos.Orientation.y);
|
||||
int c = phd_cos(boat->pos.Orientation.y);
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
int h = BOAT_WAKE;
|
||||
int w = (1 - i) * BOAT_SIDE;
|
||||
int x = boat->pos.Position.x + (-(c * w) - (h * s) >> W2V_SHIFT);
|
||||
int y = boat->pos.Position.y;
|
||||
int z = boat->pos.Position.z + ((s * w) - (h * c) >> W2V_SHIFT);
|
||||
|
||||
SPARKS* spark = &Sparks[GetFreeSpark()];
|
||||
spark->on = 1;
|
||||
spark->sR = 64;
|
||||
spark->sG = 64;
|
||||
spark->sB = 64;
|
||||
spark->dR = 64;
|
||||
spark->dG = 64;
|
||||
spark->dB = 64;
|
||||
spark->colFadeSpeed = 1;
|
||||
spark->transType = TransTypeEnum::COLADD;
|
||||
spark->life = spark->sLife = (GetRandomControl() & 3) + 6;
|
||||
spark->fadeToBlack = spark->life - 4;
|
||||
spark->x = (BOAT_SIDE * phd_sin(boat->pos.Orientation.y) >> W2V_SHIFT) + (GetRandomControl() & 128) + x - 8;
|
||||
spark->y = (GetRandomControl() & 0xF) + y - 8;
|
||||
spark->z = (BOAT_SIDE * phd_cos(boat->pos.Orientation.y) >> W2V_SHIFT) + (GetRandomControl() & 128) + z - 8;
|
||||
spark->xVel = 0;
|
||||
spark->zVel = 0;
|
||||
spark->friction = 0;
|
||||
spark->flags = 538;
|
||||
spark->yVel = (GetRandomControl() & 0x7F) - 256;
|
||||
spark->rotAng = GetRandomControl() & 0xFFF;
|
||||
spark->scalar = 3;
|
||||
spark->maxYvel = 0;
|
||||
spark->rotAdd = (GetRandomControl() & 0x1F) - 16;
|
||||
spark->gravity = -spark->yVel >> 2;
|
||||
spark->sSize = spark->size = ((GetRandomControl() & 3) + 16) * 16;
|
||||
spark->dSize = 2 * spark->size;
|
||||
|
||||
spark = &Sparks[GetFreeSpark()];
|
||||
spark->on = 1;
|
||||
spark->sR = 64;
|
||||
spark->sG = 64;
|
||||
spark->sB = 64;
|
||||
spark->dR = 64;
|
||||
spark->dG = 64;
|
||||
spark->dB = 64;
|
||||
spark->colFadeSpeed = 1;
|
||||
spark->transType = TransTypeEnum::COLADD;
|
||||
spark->life = spark->sLife = (GetRandomControl() & 3) + 6;
|
||||
spark->fadeToBlack = spark->life - 4;
|
||||
spark->x = (BOAT_SIDE * phd_sin(boat->pos.Orientation.y) >> W2V_SHIFT) + (GetRandomControl() & 128) + x - 8;
|
||||
spark->y = (GetRandomControl() & 0xF) + y - 8;
|
||||
spark->z = (BOAT_SIDE * phd_cos(boat->pos.Orientation.y) >> W2V_SHIFT) + (GetRandomControl() & 128) + z - 8;
|
||||
spark->xVel = 0;
|
||||
spark->zVel = 0;
|
||||
spark->friction = 0;
|
||||
spark->flags = 538;
|
||||
spark->yVel = (GetRandomControl() & 0x7F) - 256;
|
||||
spark->rotAng = GetRandomControl() & 0xFFF;
|
||||
spark->scalar = 3;
|
||||
spark->maxYvel = 0;
|
||||
spark->rotAdd = (GetRandomControl() & 0x1F) - 16;
|
||||
spark->gravity = -spark->yVel >> 2;
|
||||
spark->sSize = spark->size = ((GetRandomControl() & 3) + 16) * 4;
|
||||
spark->dSize = 2 * spark->size;
|
||||
spark->def = Objects[ID_DEFAULT_SPRITES].meshIndex + 17;
|
||||
}*/
|
||||
}
|
||||
|
||||
BoatMountType GetSpeedBoatMountType(ItemInfo* laraItem, ItemInfo* sBoatItem, CollisionInfo* coll)
|
||||
{
|
||||
auto* lara = GetLaraInfo(laraItem);
|
||||
|
@ -1030,6 +953,12 @@ void SpeedBoatControl(short itemNumber)
|
|||
|
||||
Camera.targetElevation = -ANGLE(20.0f);
|
||||
Camera.targetDistance = SECTOR(2);
|
||||
|
||||
auto pitch = sBoatItem->Animation.Velocity;
|
||||
sBoat->Pitch += (pitch - sBoat->Pitch) / 4;
|
||||
|
||||
int fx = (sBoatItem->Animation.Velocity > 8) ? SFX_TR2_VEHICLE_SPEEDBOAT_MOVING : (drive ? SFX_TR2_VEHICLE_SPEEDBOAT_IDLE : SFX_TR2_VEHICLE_SPEEDBOAT_ACCELERATE);
|
||||
SoundEffect(fx, &sBoatItem->Pose, SoundEnvironment::Land, 1.0f + sBoat->Pitch / (float)BOAT_MAX_VELOCITY / 4.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1039,14 +968,12 @@ void SpeedBoatControl(short itemNumber)
|
|||
sBoatItem->Pose.Orientation.z += sBoat->LeanAngle;
|
||||
}
|
||||
|
||||
auto pitch = sBoatItem->Animation.Velocity;
|
||||
sBoat->Pitch += (pitch - sBoat->Pitch) / 4;
|
||||
|
||||
int fx = (sBoatItem->Animation.Velocity > 8) ? SFX_TR2_SPEEDBOAT_MOVING : (drive ? SFX_TR2_SPEEDBOAT_IDLE : SFX_TR2_SPEEDBOAT_ACCELERATE);
|
||||
SoundEffect(fx, &sBoatItem->Pose, SoundEnvironment::Land, 1.0f + sBoat->Pitch / (float)BOAT_MAX_VELOCITY / 4.0f);
|
||||
|
||||
if (sBoatItem->Animation.Velocity && (water - 5) == sBoatItem->Pose.Position.y)
|
||||
DoBoatWakeEffect(sBoatItem);
|
||||
{
|
||||
auto room = probe.Block->RoomBelow(sBoatItem->Pose.Position.x, sBoatItem->Pose.Position.z).value_or(NO_ROOM);
|
||||
if (room != NO_ROOM && (TestEnvironment(RoomEnvFlags::ENV_FLAG_WATER, room) || TestEnvironment(RoomEnvFlags::ENV_FLAG_SWAMP, room)))
|
||||
TEN::Effects::TriggerSpeedboatFoam(sBoatItem, Vector3(0, 0, -BOAT_BACK));
|
||||
}
|
||||
|
||||
if (lara->Vehicle != itemNumber)
|
||||
return;
|
||||
|
|
|
@ -12,7 +12,6 @@ enum class BoatMountType
|
|||
};
|
||||
|
||||
void InitialiseSpeedBoat(short itemNumber);
|
||||
void DoBoatWakeEffect(ItemInfo* sBoatItem);
|
||||
BoatMountType GetSpeedBoatMountType(ItemInfo* laraItem, ItemInfo* sBoatItem, CollisionInfo* coll);
|
||||
bool TestSpeedBoatDismount(ItemInfo* sBoatItem, int direction);
|
||||
void DoSpeedBoatDismount(ItemInfo* laraItem, ItemInfo* sBoatItem);
|
||||
|
|
|
@ -439,7 +439,7 @@ void SkidooExplode(ItemInfo* laraItem, ItemInfo* skidooItem)
|
|||
pos.Orientation.z = 0;
|
||||
|
||||
TriggerShockwave(&pos, 50, 180, 40, GenerateFloat(160, 200), 60, 60, 64, GenerateFloat(0, 359), 0);
|
||||
//ExplodingDeath(lara->Vehicle, -1, 256);
|
||||
//ExplodingDeath(lara->Vehicle, ALL_JOINT_BITS, 256);
|
||||
|
||||
KillItem(lara->Vehicle);
|
||||
skidooItem->Status = ITEM_DEACTIVATED;
|
||||
|
@ -523,13 +523,13 @@ bool SkidooControl(ItemInfo* laraItem, CollisionInfo* coll)
|
|||
skidoo->TrackMesh = ((skidoo->TrackMesh & 3) == 1) ? 2 : 1;
|
||||
|
||||
skidoo->Pitch += (pitch - skidoo->Pitch) / 4;
|
||||
SoundEffect(skidoo->Pitch ? SFX_TR2_SNOWMOBILE_MOVING : SFX_TR2_SNOWMOBILE_ACCELERATE, &skidooItem->Pose, SoundEnvironment::Land, 0.5f + skidoo->Pitch / (float)SKIDOO_MAX_VELOCITY);
|
||||
SoundEffect(skidoo->Pitch ? SFX_TR2_VEHICLE_SNOWMOBILE_MOVING : SFX_TR2_VEHICLE_SNOWMOBILE_ACCELERATE, &skidooItem->Pose, SoundEnvironment::Land, 0.5f + skidoo->Pitch / (float)SKIDOO_MAX_VELOCITY);
|
||||
}
|
||||
else
|
||||
{
|
||||
skidoo->TrackMesh = 0;
|
||||
if (!drive)
|
||||
SoundEffect(SFX_TR2_SNOWMOBILE_IDLE, &skidooItem->Pose);
|
||||
SoundEffect(SFX_TR2_VEHICLE_SNOWMOBILE_IDLE, &skidooItem->Pose);
|
||||
skidoo->Pitch = 0;
|
||||
}
|
||||
skidooItem->Floor = height;
|
||||
|
@ -716,9 +716,9 @@ void SkidooAnimation(ItemInfo* laraItem, ItemInfo* skidooItem, int collide, bool
|
|||
if (laraItem->Animation.ActiveState != SKIDOO_STATE_HIT)
|
||||
{
|
||||
if (collide == SKIDOO_ANIM_HIT_FRONT)
|
||||
SoundEffect(SFX_TR2_VEHICLE_IMPACT_1, &skidooItem->Pose);
|
||||
SoundEffect(SFX_TR2_VEHICLE_IMPACT1, &skidooItem->Pose);
|
||||
else
|
||||
SoundEffect(SFX_TR2_VEHICLE_IMPACT_2, &skidooItem->Pose);
|
||||
SoundEffect(SFX_TR2_VEHICLE_IMPACT2, &skidooItem->Pose);
|
||||
|
||||
laraItem->Animation.AnimNumber = Objects[ID_SNOWMOBILE_LARA_ANIMS].animIndex + collide;
|
||||
laraItem->Animation.FrameNumber = g_Level.Anims[laraItem->Animation.AnimNumber].frameBase;
|
||||
|
@ -794,7 +794,7 @@ void SkidooAnimation(ItemInfo* laraItem, ItemInfo* skidooItem, int collide, bool
|
|||
skidoo->RightVerticalVelocity <= 0)
|
||||
{
|
||||
laraItem->Animation.TargetState = SKIDOO_STATE_SIT;
|
||||
SoundEffect(SFX_TR2_VEHICLE_IMPACT_3, &skidooItem->Pose);
|
||||
SoundEffect(SFX_TR2_VEHICLE_IMPACT3, &skidooItem->Pose);
|
||||
}
|
||||
else if (skidooItem->Animation.VerticalVelocity > (DAMAGE_START + DAMAGE_LENGTH))
|
||||
laraItem->Animation.TargetState = SKIDOO_STATE_JUMP_OFF;
|
||||
|
|
|
@ -2,9 +2,11 @@
|
|||
#include "Objects/TR3/Entity/tr3_flamethrower.h"
|
||||
|
||||
#include "Game/animation.h"
|
||||
#include "Game/camera.h"
|
||||
#include "Game/control/box.h"
|
||||
#include "Game/control/lot.h"
|
||||
#include "Game/effects/effects.h"
|
||||
#include "Game/effects/tomb4fx.h"
|
||||
#include "Game/items.h"
|
||||
#include "Game/itemdata/creature_info.h"
|
||||
#include "Game/Lara/lara.h"
|
||||
|
@ -15,6 +17,7 @@
|
|||
#include "Specific/setup.h"
|
||||
|
||||
BITE_INFO FlamethrowerBite = { 0, 340, 64, 7 };
|
||||
Vector3Int FlamethrowerOffset = { 0, 340, 0 };
|
||||
|
||||
// TODO
|
||||
enum FlamethrowerState
|
||||
|
@ -28,186 +31,6 @@ enum FlamethrowerAnim
|
|||
|
||||
};
|
||||
|
||||
static void TriggerPilotFlame(int itemNumber)
|
||||
{
|
||||
int dx = LaraItem->Pose.Position.x - g_Level.Items[itemNumber].Pose.Position.x;
|
||||
int dz = LaraItem->Pose.Position.z - g_Level.Items[itemNumber].Pose.Position.z;
|
||||
|
||||
if (dx < -SECTOR(16) || dx > SECTOR(16) || dz < -SECTOR(16) || dz > SECTOR(16))
|
||||
return;
|
||||
|
||||
auto* spark = &Sparks[GetFreeSpark()];
|
||||
|
||||
spark->on = 1;
|
||||
spark->sR = 48 + (GetRandomControl() & 31);
|
||||
spark->sG = spark->sR;
|
||||
spark->sB = 192 + (GetRandomControl() & 63);
|
||||
|
||||
spark->dR = 192 + (GetRandomControl() & 63);
|
||||
spark->dG = 128 + (GetRandomControl() & 63);
|
||||
spark->dB = 32;
|
||||
|
||||
spark->colFadeSpeed = 12 + (GetRandomControl() & 3);
|
||||
spark->fadeToBlack = 4;
|
||||
spark->sLife = spark->life = (GetRandomControl() & 3) + 20;
|
||||
spark->transType = TransTypeEnum::COLADD;
|
||||
spark->extras = 0;
|
||||
spark->dynamic = -1;
|
||||
spark->x = (GetRandomControl() & 31) - 16;
|
||||
spark->y = (GetRandomControl() & 31) - 16;
|
||||
spark->z = (GetRandomControl() & 31) - 16;
|
||||
|
||||
spark->xVel = (GetRandomControl() & 31) - 16;
|
||||
spark->yVel = -(GetRandomControl() & 3);
|
||||
spark->zVel = (GetRandomControl() & 31) - 16;
|
||||
|
||||
spark->flags = SP_SCALE | SP_DEF | SP_EXPDEF | SP_ITEM | SP_NODEATTACH;
|
||||
spark->fxObj = itemNumber;
|
||||
spark->nodeNumber = 0;
|
||||
spark->friction = 4;
|
||||
spark->gravity = -(GetRandomControl() & 3) - 2;
|
||||
spark->maxYvel = -(GetRandomControl() & 3) - 4;
|
||||
//spark->def = Objects[EXPLOSION1].mesh_index;
|
||||
spark->scalar = 0;
|
||||
int size = (GetRandomControl() & 7) + 32;
|
||||
spark->size = size / 2;
|
||||
spark->dSize = size;
|
||||
}
|
||||
|
||||
static void TriggerFlamethrowerFlame(int x, int y, int z, int xv, int yv, int zv, int fxNumber)
|
||||
{
|
||||
auto* spark = &Sparks[GetFreeSpark()];
|
||||
|
||||
spark->on = true;
|
||||
spark->sR = 48 + (GetRandomControl() & 31);
|
||||
spark->sG = spark->sR;
|
||||
spark->sB = 192 + (GetRandomControl() & 63);
|
||||
|
||||
spark->dR = 192 + (GetRandomControl() & 63);
|
||||
spark->dG = 128 + (GetRandomControl() & 63);
|
||||
spark->dB = 32;
|
||||
|
||||
if (xv || yv || zv)
|
||||
{
|
||||
spark->colFadeSpeed = 6;
|
||||
spark->fadeToBlack = 2;
|
||||
spark->sLife = spark->life = (GetRandomControl() & 1) + 12;
|
||||
}
|
||||
else
|
||||
{
|
||||
spark->colFadeSpeed = 8;
|
||||
spark->fadeToBlack = 16;
|
||||
spark->sLife = spark->life = (GetRandomControl() & 3) + 20;
|
||||
}
|
||||
|
||||
spark->transType = TransTypeEnum::COLADD;
|
||||
|
||||
spark->extras = 0;
|
||||
spark->dynamic = -1;
|
||||
|
||||
spark->x = x + ((GetRandomControl() & 31) - 16);
|
||||
spark->y = y;
|
||||
spark->z = z + ((GetRandomControl() & 31) - 16);
|
||||
|
||||
spark->xVel = ((GetRandomControl() & 15) - 16) + xv;
|
||||
spark->yVel = yv;
|
||||
spark->zVel = ((GetRandomControl() & 15) - 16) + zv;
|
||||
spark->friction = 0;
|
||||
|
||||
if (GetRandomControl() & 1)
|
||||
{
|
||||
if (fxNumber >= 0)
|
||||
spark->flags = SP_SCALE | SP_DEF | SP_ROTATE | SP_EXPDEF | SP_FX;
|
||||
else
|
||||
spark->flags = SP_SCALE | SP_DEF | SP_ROTATE | SP_EXPDEF;
|
||||
|
||||
spark->rotAng = GetRandomControl() & 4095;
|
||||
if (GetRandomControl() & 1)
|
||||
spark->rotAdd = -(GetRandomControl() & 15) - 16;
|
||||
else
|
||||
spark->rotAdd = (GetRandomControl() & 15) + 16;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fxNumber >= 0)
|
||||
spark->flags = SP_SCALE | SP_DEF | SP_EXPDEF | SP_FX;
|
||||
else
|
||||
spark->flags = SP_SCALE | SP_DEF | SP_EXPDEF;
|
||||
}
|
||||
|
||||
spark->fxObj = fxNumber;
|
||||
spark->gravity = 0;
|
||||
spark->maxYvel = 0;
|
||||
|
||||
int size = (GetRandomControl() & 31) + 64;
|
||||
|
||||
if (xv || yv || zv)
|
||||
{
|
||||
spark->size = size / 32;
|
||||
if (fxNumber == -2)
|
||||
spark->scalar = 2;
|
||||
else
|
||||
spark->scalar = 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
spark->size = size / 16;
|
||||
spark->scalar = 4;
|
||||
}
|
||||
|
||||
spark->dSize = size / 2;
|
||||
}
|
||||
|
||||
static short TriggerFlameThrower(ItemInfo* item, BITE_INFO* bite, short speed)
|
||||
{
|
||||
short effectNumber = CreateNewEffect(item->RoomNumber);
|
||||
if (effectNumber != NO_ITEM)
|
||||
{
|
||||
auto* fx = &EffectList[effectNumber];
|
||||
|
||||
auto pos1 = Vector3Int(bite->x, bite->y, bite->z);
|
||||
GetJointAbsPosition(item, &pos1, bite->meshNum);
|
||||
|
||||
auto pos2 = Vector3Int(bite->x, bite->y / 2, bite->z);
|
||||
GetJointAbsPosition(item, &pos2, bite->meshNum);
|
||||
|
||||
auto angles = GetVectorAngles(pos2.x - pos1.x, pos2.y - pos1.y, pos2.z - pos1.z);
|
||||
|
||||
fx->pos.Position = pos1;
|
||||
fx->pos.Orientation = angles;
|
||||
fx->roomNumber = item->RoomNumber;
|
||||
fx->speed = speed * 4;
|
||||
fx->counter = 20;
|
||||
fx->flag1 = 0;
|
||||
|
||||
TriggerFlamethrowerFlame(0, 0, 0, 0, 0, 0, effectNumber);
|
||||
|
||||
int velocity;
|
||||
int xv, yv, zv;
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
speed = (GetRandomControl() % (speed * 4)) + 32;
|
||||
velocity = speed * phd_cos(fx->pos.Orientation.x);
|
||||
|
||||
xv = velocity * phd_sin(fx->pos.Orientation.y);
|
||||
yv = -speed * phd_sin(fx->pos.Orientation.x);
|
||||
zv = velocity * phd_cos(fx->pos.Orientation.y);
|
||||
|
||||
TriggerFlamethrowerFlame(fx->pos.Position.x, fx->pos.Position.y, fx->pos.Position.z, xv * 32, yv * 32, zv * 32, -1);
|
||||
}
|
||||
|
||||
velocity = (speed * 2) * phd_cos(fx->pos.Orientation.x);
|
||||
zv = velocity * phd_cos(fx->pos.Orientation.y);
|
||||
xv = velocity * phd_sin(fx->pos.Orientation.y);
|
||||
yv = -(speed * 2) * phd_sin(fx->pos.Orientation.x);
|
||||
|
||||
TriggerFlamethrowerFlame(fx->pos.Position.x, fx->pos.Position.y, fx->pos.Position.z, xv * 32, yv * 32, zv * 32, -2);
|
||||
}
|
||||
|
||||
return effectNumber;
|
||||
}
|
||||
|
||||
void FlameThrowerControl(short itemNumber)
|
||||
{
|
||||
if (!CreatureActive(itemNumber))
|
||||
|
@ -229,10 +52,12 @@ void FlameThrowerControl(short itemNumber)
|
|||
if (item->Animation.ActiveState != 6 && item->Animation.ActiveState != 11)
|
||||
{
|
||||
TriggerDynamicLight(pos.x, pos.y, pos.z, (random & 3) + 6, 24 - ((random / 16) & 3), 16 - ((random / 64) & 3), random & 3);
|
||||
TriggerPilotFlame(itemNumber);
|
||||
TriggerPilotFlame(itemNumber, 9);
|
||||
}
|
||||
else
|
||||
{
|
||||
TriggerDynamicLight(pos.x, pos.y, pos.z, (random & 3) + 10, 31 - ((random / 16) & 3), 24 - ((random / 64) & 3), random & 7);
|
||||
}
|
||||
|
||||
if (item->HitPoints <= 0)
|
||||
{
|
||||
|
@ -466,10 +291,10 @@ void FlameThrowerControl(short itemNumber)
|
|||
item->Animation.TargetState = 1;
|
||||
|
||||
if (creature->Flags < 40)
|
||||
TriggerFlameThrower(item, &FlamethrowerBite, creature->Flags);
|
||||
ThrowFire(itemNumber, FlamethrowerBite.meshNum, FlamethrowerOffset, Vector3Int(0, creature->Flags * 1.5f, 0));
|
||||
else
|
||||
{
|
||||
TriggerFlameThrower(item, &FlamethrowerBite, (GetRandomControl() & 31) + 12);
|
||||
ThrowFire(itemNumber, FlamethrowerBite.meshNum, FlamethrowerOffset, Vector3Int(0, (GetRandomControl() & 63) + 12, 0));
|
||||
if (realEnemy)
|
||||
{
|
||||
/*code*/
|
||||
|
@ -501,10 +326,10 @@ void FlameThrowerControl(short itemNumber)
|
|||
item->Animation.TargetState = 2;
|
||||
|
||||
if (creature->Flags < 40)
|
||||
TriggerFlameThrower(item, &FlamethrowerBite, creature->Flags);
|
||||
ThrowFire(itemNumber, FlamethrowerBite.meshNum, FlamethrowerOffset, Vector3Int(0, creature->Flags * 1.5f, 0));
|
||||
else
|
||||
{
|
||||
TriggerFlameThrower(item, &FlamethrowerBite, (GetRandomControl() & 31) + 12);
|
||||
ThrowFire(itemNumber, FlamethrowerBite.meshNum, FlamethrowerOffset, Vector3Int(0, (GetRandomControl() & 63) + 12, 0));
|
||||
if (realEnemy)
|
||||
{
|
||||
/*code*/
|
||||
|
|
|
@ -44,7 +44,7 @@ void MonkeyControl(short itemNumber)
|
|||
{
|
||||
if (item->Animation.ActiveState != 11)
|
||||
{
|
||||
item->MeshBits = -1;
|
||||
item->MeshBits = ALL_JOINT_BITS;
|
||||
item->Animation.AnimNumber = Objects[ID_MONKEY].animIndex + 14;
|
||||
item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase;
|
||||
item->Animation.ActiveState = 11;
|
||||
|
@ -91,7 +91,7 @@ void MonkeyControl(short itemNumber)
|
|||
if (item->CarriedItem != NO_ITEM)
|
||||
item->MeshBits = 0xFFFFFEFF;
|
||||
else
|
||||
item->MeshBits = -1;
|
||||
item->MeshBits = ALL_JOINT_BITS;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -102,6 +102,7 @@ void MPGunControl(short itemNumber)
|
|||
torsoY = AI.angle;
|
||||
ShotLara(item, &AI, &MPGunBite, torsoY, 32);
|
||||
SoundEffect(SFX_TR3_OIL_SMG_FIRE, &item->Pose, SoundEnvironment::Land, 1.0f, 0.7f);
|
||||
creature->FiredWeapon = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,8 @@
|
|||
#include "Sound/sound.h"
|
||||
#include "Specific/level.h"
|
||||
#include "Specific/setup.h"
|
||||
#include "camera.h"
|
||||
#include "Game/camera.h"
|
||||
#include "Renderer/Renderer11Enums.h"
|
||||
|
||||
BITE_INFO ShivaBiteLeft = { 0, 0, 920, 13 };
|
||||
BITE_INFO ShivaBiteRight = { 0, 0, 920, 22 };
|
||||
|
@ -71,7 +72,7 @@ static void TriggerShivaSmoke(long x, long y, long z, long uw)
|
|||
return;
|
||||
}
|
||||
|
||||
auto* sptr = &Sparks[GetFreeSpark()];
|
||||
auto* sptr = GetFreeParticle();
|
||||
|
||||
sptr->on = 1;
|
||||
if (uw)
|
||||
|
@ -98,9 +99,9 @@ static void TriggerShivaSmoke(long x, long y, long z, long uw)
|
|||
sptr->sLife = sptr->life = (GetRandomControl() & 31) + 96;
|
||||
|
||||
if (uw)
|
||||
sptr->transType = TransTypeEnum::COLADD;
|
||||
sptr->blendMode = BLEND_MODES::BLENDMODE_ADDITIVE;
|
||||
else
|
||||
sptr->transType = TransTypeEnum::COLADD;
|
||||
sptr->blendMode = BLEND_MODES::BLENDMODE_ADDITIVE;
|
||||
|
||||
sptr->extras = 0;
|
||||
sptr->dynamic = -1;
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "Sound/sound.h"
|
||||
#include "Specific/level.h"
|
||||
#include "Specific/setup.h"
|
||||
#include "Renderer/Renderer11Enums.h"
|
||||
|
||||
using namespace TEN::Effects::Lara;
|
||||
|
||||
|
@ -62,7 +63,7 @@ enum TonyAnim
|
|||
static BOSS_STRUCT BossData;
|
||||
|
||||
#define TONY_TURN ANGLE(2.0f)
|
||||
#define TONY_HITS 1 // Tony Harder To Kill, was 100 (6 shotgun shots)
|
||||
#define TONY_HITS 100
|
||||
#define MAX_TONY_TRIGGER_RANGE 0x4000
|
||||
|
||||
void InitialiseTony(short itemNumber)
|
||||
|
@ -119,7 +120,7 @@ static void TriggerTonyFlame(short itemNumber, int hand)
|
|||
if (dx < -MAX_TONY_TRIGGER_RANGE || dx > MAX_TONY_TRIGGER_RANGE || dz < -MAX_TONY_TRIGGER_RANGE || dz > MAX_TONY_TRIGGER_RANGE)
|
||||
return;
|
||||
|
||||
auto* sptr = &Sparks[GetFreeSpark()];
|
||||
auto* sptr = GetFreeParticle();
|
||||
|
||||
sptr->on = true;
|
||||
sptr->sR = 255;
|
||||
|
@ -131,7 +132,7 @@ static void TriggerTonyFlame(short itemNumber, int hand)
|
|||
sptr->colFadeSpeed = 12 + (GetRandomControl() & 3);
|
||||
sptr->fadeToBlack = 8;
|
||||
sptr->sLife = sptr->life = (GetRandomControl() & 7) + 24;
|
||||
sptr->transType = TransTypeEnum::COLADD;
|
||||
sptr->blendMode = BLEND_MODES::BLENDMODE_ADDITIVE;
|
||||
sptr->extras = NULL;
|
||||
sptr->dynamic = -1;
|
||||
sptr->x = ((GetRandomControl() & 15) - 8);
|
||||
|
@ -158,7 +159,7 @@ static void TriggerTonyFlame(short itemNumber, int hand)
|
|||
sptr->maxYvel = -(GetRandomControl() & 7) - 16;
|
||||
sptr->fxObj = itemNumber;
|
||||
sptr->nodeNumber = hand;
|
||||
sptr->def = Objects[ID_DEFAULT_SPRITES].meshIndex;
|
||||
sptr->spriteIndex = Objects[ID_DEFAULT_SPRITES].meshIndex;
|
||||
sptr->scalar = 1;
|
||||
unsigned char size = (GetRandomControl() & 31) + 32;
|
||||
sptr->size = size;
|
||||
|
@ -173,7 +174,7 @@ static void TriggerFireBallFlame(short fxNumber, long type, long xv, long yv, lo
|
|||
if (dx < -MAX_TONY_TRIGGER_RANGE || dx > MAX_TONY_TRIGGER_RANGE || dz < -MAX_TONY_TRIGGER_RANGE || dz > MAX_TONY_TRIGGER_RANGE)
|
||||
return;
|
||||
|
||||
auto* sptr = &Sparks[GetFreeSpark()];
|
||||
auto* sptr = GetFreeParticle();
|
||||
|
||||
sptr->on = true;
|
||||
sptr->sR = 255;
|
||||
|
@ -185,7 +186,7 @@ static void TriggerFireBallFlame(short fxNumber, long type, long xv, long yv, lo
|
|||
sptr->colFadeSpeed = 12 + (GetRandomControl() & 3);
|
||||
sptr->fadeToBlack = 8;
|
||||
sptr->sLife = sptr->life = (GetRandomControl() & 7) + 24;
|
||||
sptr->transType = TransTypeEnum::COLADD;
|
||||
sptr->blendMode = BLEND_MODES::BLENDMODE_ADDITIVE;
|
||||
sptr->extras = 0;
|
||||
sptr->dynamic = -1;
|
||||
sptr->x = ((GetRandomControl() & 15) - 8);
|
||||
|
@ -209,7 +210,7 @@ static void TriggerFireBallFlame(short fxNumber, long type, long xv, long yv, lo
|
|||
sptr->flags = SP_SCALE | SP_DEF | SP_EXPDEF | SP_FX;
|
||||
|
||||
sptr->fxObj = (unsigned char)fxNumber;
|
||||
sptr->def = (unsigned char)Objects[ID_DEFAULT_SPRITES].meshIndex;
|
||||
sptr->spriteIndex = (unsigned char)Objects[ID_DEFAULT_SPRITES].meshIndex;
|
||||
sptr->scalar = 1;
|
||||
unsigned char size = (GetRandomControl() & 31) + 64;
|
||||
sptr->size = size;
|
||||
|
|
|
@ -264,7 +264,7 @@ static void CartToEntityCollision(ItemInfo* laraItem, ItemInfo* minecartItem)
|
|||
int frame = laraItem->Animation.FrameNumber - g_Level.Anims[laraItem->Animation.AnimNumber].frameBase;
|
||||
if (frame >= 12 && frame <= 22)
|
||||
{
|
||||
SoundEffect(SFX_TR3_SPANNER, &item->Pose, SoundEnvironment::Always);
|
||||
SoundEffect(SFX_TR3_VEHICLE_MINECART_WRENCH, &item->Pose, SoundEnvironment::Always);
|
||||
TestTriggers(item, true);
|
||||
item->Animation.FrameNumber++;
|
||||
}
|
||||
|
@ -392,21 +392,21 @@ static void MoveCart(ItemInfo* laraItem, ItemInfo* minecartItem)
|
|||
if (minecartItem->Animation.Velocity < CART_MIN_VEL)
|
||||
{
|
||||
minecartItem->Animation.Velocity = CART_MIN_VEL;
|
||||
StopSoundEffect(SFX_TR3_MINE_CART_TRACK_LOOP);
|
||||
StopSoundEffect(SFX_TR3_VEHICLE_MINECART_TRACK_LOOP);
|
||||
|
||||
if (minecart->VerticalVelocity)
|
||||
StopSoundEffect(SFX_TR3_MINE_CART_PULLY_LOOP);
|
||||
StopSoundEffect(SFX_TR3_VEHICLE_MINECART_PULLY_LOOP);
|
||||
else
|
||||
SoundEffect(SFX_TR3_MINE_CART_PULLY_LOOP, &minecartItem->Pose, SoundEnvironment::Always);
|
||||
SoundEffect(SFX_TR3_VEHICLE_MINECART_PULLY_LOOP, &minecartItem->Pose, SoundEnvironment::Always);
|
||||
}
|
||||
else
|
||||
{
|
||||
StopSoundEffect(SFX_TR3_MINE_CART_PULLY_LOOP);
|
||||
StopSoundEffect(SFX_TR3_VEHICLE_MINECART_PULLY_LOOP);
|
||||
|
||||
if (minecart->VerticalVelocity)
|
||||
StopSoundEffect(SFX_TR3_MINE_CART_TRACK_LOOP);
|
||||
StopSoundEffect(SFX_TR3_VEHICLE_MINECART_TRACK_LOOP);
|
||||
else
|
||||
SoundEffect(SFX_TR3_MINE_CART_TRACK_LOOP, &minecartItem->Pose, SoundEnvironment::Land, 1.0f + ((float)minecartItem->Animation.Velocity / SECTOR(8))); // TODO: check actual sound!
|
||||
SoundEffect(SFX_TR3_VEHICLE_MINECART_TRACK_LOOP, &minecartItem->Pose, SoundEnvironment::Land, 1.0f + ((float)minecartItem->Animation.Velocity / SECTOR(8))); // TODO: check actual sound!
|
||||
}
|
||||
|
||||
if (minecart->Flags & (CART_FLAG_TURNING_LEFT | CART_FLAG_TURNING_RIGHT))
|
||||
|
@ -487,7 +487,7 @@ static void MoveCart(ItemInfo* laraItem, ItemInfo* minecartItem)
|
|||
if (minecartItem->Pose.Position.y > minecart->FloorHeightMiddle)
|
||||
{
|
||||
if (minecart->VerticalVelocity > 0)
|
||||
SoundEffect(SFX_TR3_QUADBIKE_FRONT_IMPACT, &minecartItem->Pose, SoundEnvironment::Always);
|
||||
SoundEffect(SFX_TR3_VEHICLE_QUADBIKE_FRONT_IMPACT, &minecartItem->Pose, SoundEnvironment::Always);
|
||||
|
||||
minecartItem->Pose.Position.y = minecart->FloorHeightMiddle;
|
||||
minecart->VerticalVelocity = 0;
|
||||
|
@ -597,7 +597,7 @@ static void DoUserInput(ItemInfo* minecartItem, ItemInfo* laraItem, MinecartInfo
|
|||
case CART_STATE_IDLE:
|
||||
if (!(minecart->Flags & CART_FLAG_CONTROL))
|
||||
{
|
||||
SoundEffect(SFX_TR3_MINE_CART_START, &minecartItem->Pose, SoundEnvironment::Always);
|
||||
SoundEffect(SFX_TR3_VEHICLE_MINECART_START, &minecartItem->Pose, SoundEnvironment::Always);
|
||||
minecart->Flags |= CART_FLAG_CONTROL;
|
||||
minecart->StopDelay = 64;
|
||||
}
|
||||
|
@ -641,17 +641,17 @@ static void DoUserInput(ItemInfo* minecartItem, ItemInfo* laraItem, MinecartInfo
|
|||
if (TrInput & CART_IN_DUCK)
|
||||
{
|
||||
laraItem->Animation.TargetState = CART_STATE_DUCK;
|
||||
StopSoundEffect(SFX_TR3_MINE_CART_BRAKE);
|
||||
StopSoundEffect(SFX_TR3_VEHICLE_MINECART_BRAKE);
|
||||
}
|
||||
else if (!(TrInput & CART_IN_BRAKE) || minecart->Flags & CART_FLAG_STOPPED)
|
||||
{
|
||||
laraItem->Animation.TargetState = CART_STATE_MOVE;
|
||||
StopSoundEffect(SFX_TR3_MINE_CART_BRAKE);
|
||||
StopSoundEffect(SFX_TR3_VEHICLE_MINECART_BRAKE);
|
||||
}
|
||||
else
|
||||
{
|
||||
minecart->Velocity += CART_DEC;
|
||||
SoundEffect(SFX_TR3_MINE_CART_BRAKE, &laraItem->Pose, SoundEnvironment::Always);
|
||||
SoundEffect(SFX_TR3_VEHICLE_MINECART_BRAKE, &laraItem->Pose, SoundEnvironment::Always);
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -682,16 +682,11 @@ static void DoUserInput(ItemInfo* minecartItem, ItemInfo* laraItem, MinecartInfo
|
|||
if (laraItem->Animation.AnimNumber == Objects[ID_MINECART_LARA_ANIMS].animIndex + 1 &&
|
||||
laraItem->Animation.FrameNumber == g_Level.Anims[laraItem->Animation.AnimNumber].frameEnd)
|
||||
{
|
||||
Vector3Int pos = { 0, 640, 0 };
|
||||
auto pos = Vector3Int(0, 640, 0);
|
||||
GetLaraJointPosition(&pos, LM_HIPS);
|
||||
|
||||
laraItem->Pose.Position.x = pos.x;
|
||||
laraItem->Pose.Position.y = pos.y;
|
||||
laraItem->Pose.Position.z = pos.z;
|
||||
laraItem->Pose.Orientation.x = 0;
|
||||
laraItem->Pose.Orientation.y = ANGLE(90.0f);
|
||||
laraItem->Pose.Orientation.z = 0;
|
||||
minecartItem->Pose.Orientation.y + ANGLE(90.0f);
|
||||
laraItem->Pose.Position = pos;
|
||||
laraItem->Pose.Orientation = Vector3Shrt(0, minecartItem->Pose.Orientation.y + ANGLE(90.0f), 0);
|
||||
|
||||
SetAnimation(laraItem, LA_STAND_SOLID);
|
||||
lara->Control.HandStatus = HandStatus::Free;
|
||||
|
@ -704,16 +699,11 @@ static void DoUserInput(ItemInfo* minecartItem, ItemInfo* laraItem, MinecartInfo
|
|||
if (laraItem->Animation.AnimNumber == Objects[ID_MINECART_LARA_ANIMS].animIndex + 47 &&
|
||||
laraItem->Animation.FrameNumber == g_Level.Anims[laraItem->Animation.AnimNumber].frameEnd)
|
||||
{
|
||||
Vector3Int pos = { 0, 640, 0 };
|
||||
auto pos = Vector3Int(0, 640, 0);
|
||||
GetLaraJointPosition(&pos, LM_HIPS);
|
||||
|
||||
laraItem->Pose.Position.x = pos.x;
|
||||
laraItem->Pose.Position.y = pos.y;
|
||||
laraItem->Pose.Position.z = pos.z;
|
||||
laraItem->Pose.Orientation.x = 0;
|
||||
laraItem->Pose.Orientation.y = ANGLE(90.0f);
|
||||
laraItem->Pose.Orientation.z = 0;
|
||||
minecartItem->Pose.Orientation.y + ANGLE(90.0f);
|
||||
laraItem->Pose.Position = pos;
|
||||
laraItem->Pose.Orientation = Vector3Shrt(0, minecartItem->Pose.Orientation.y - ANGLE(90.0f), 0);
|
||||
|
||||
SetAnimation(laraItem, LA_STAND_SOLID);
|
||||
lara->Control.HandStatus = HandStatus::Free;
|
||||
|
@ -752,7 +742,7 @@ static void DoUserInput(ItemInfo* minecartItem, ItemInfo* laraItem, MinecartInfo
|
|||
floorHeight < CLICK(1))
|
||||
{
|
||||
if (Wibble & 7 == 0)
|
||||
SoundEffect(SFX_TR3_QUADBIKE_FRONT_IMPACT, &minecartItem->Pose, SoundEnvironment::Always);
|
||||
SoundEffect(SFX_TR3_VEHICLE_QUADBIKE_FRONT_IMPACT, &minecartItem->Pose, SoundEnvironment::Always);
|
||||
|
||||
minecartItem->Pose.Position.x += TURN_DEATH_VEL * phd_sin(minecartItem->Pose.Orientation.y);
|
||||
minecartItem->Pose.Position.z += TURN_DEATH_VEL * phd_cos(minecartItem->Pose.Orientation.y);
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "Specific/input.h"
|
||||
#include "Specific/setup.h"
|
||||
#include "Specific/prng.h"
|
||||
#include "Game/particle/SimpleParticle.h"
|
||||
|
||||
using std::vector;
|
||||
using namespace TEN::Math::Random;
|
||||
|
@ -60,6 +61,12 @@ using namespace TEN::Math::Random;
|
|||
#define MAX_MOMENTUM_TURN ANGLE(1.5f)
|
||||
#define QUAD_MAX_MOM_TURN ANGLE(150.0f)
|
||||
|
||||
#define QUAD_MAX_WATER_HEIGHT CLICK(2)
|
||||
#define QUAD_WATER_VEL_COEFFICIENT 16.0f
|
||||
#define QUAD_WATER_TURN_COEFFICIENT 10.0f
|
||||
#define QUAD_SWAMP_VEL_COEFFICIENT 8.0f
|
||||
#define QUAD_SWAMP_TURN_COEFFICIENT 6.0f
|
||||
|
||||
#define QUAD_MAX_HEIGHT CLICK(1)
|
||||
#define QUAD_MIN_BOUNCE ((MAX_VELOCITY / 2) / CLICK(1))
|
||||
|
||||
|
@ -260,10 +267,10 @@ static bool QuadCheckGetOff(ItemInfo* laraItem, ItemInfo* quadItem)
|
|||
GetJointAbsPosition(laraItem, &pos, LM_HIPS);
|
||||
|
||||
laraItem->Pose.Position = pos;
|
||||
laraItem->Pose.Orientation.x = 0;
|
||||
laraItem->Pose.Orientation.z = 0;
|
||||
laraItem->Animation.Airborne = true;
|
||||
laraItem->Animation.VerticalVelocity = quadItem->Animation.VerticalVelocity;
|
||||
laraItem->Pose.Orientation.x = 0;
|
||||
laraItem->Pose.Orientation.z = 0;
|
||||
laraItem->HitPoints = 0;
|
||||
lara->Control.HandStatus = HandStatus::Free;
|
||||
quadItem->Flags |= ONESHOT;
|
||||
|
@ -273,8 +280,8 @@ static bool QuadCheckGetOff(ItemInfo* laraItem, ItemInfo* quadItem)
|
|||
else if (laraItem->Animation.ActiveState == QUAD_STATE_FALL_DEATH)
|
||||
{
|
||||
laraItem->Animation.TargetState = LS_DEATH;
|
||||
laraItem->Animation.VerticalVelocity = DAMAGE_START + DAMAGE_LENGTH;
|
||||
laraItem->Animation.Velocity = 0;
|
||||
laraItem->Animation.VerticalVelocity = DAMAGE_START + DAMAGE_LENGTH;
|
||||
quad->Flags |= QUAD_FLAG_DEAD;
|
||||
|
||||
return false;
|
||||
|
@ -841,7 +848,7 @@ static void AnimateQuadBike(ItemInfo* laraItem, ItemInfo* quadItem, int collide,
|
|||
}
|
||||
|
||||
laraItem->Animation.FrameNumber = GetFrameNumber(laraItem, laraItem->Animation.AnimNumber);
|
||||
SoundEffect(SFX_TR3_QUADBIKE_FRONT_IMPACT, &quadItem->Pose);
|
||||
SoundEffect(SFX_TR3_VEHICLE_QUADBIKE_FRONT_IMPACT, &quadItem->Pose);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -962,6 +969,37 @@ static void AnimateQuadBike(ItemInfo* laraItem, ItemInfo* quadItem, int collide,
|
|||
|
||||
if (TestEnvironment(ENV_FLAG_WATER, quadItem) ||
|
||||
TestEnvironment(ENV_FLAG_SWAMP, quadItem))
|
||||
{
|
||||
auto waterDepth = (float)GetWaterDepth(quadItem);
|
||||
|
||||
// HACK: Sometimes quadbike test position may end up under non-portal ceiling block.
|
||||
// GetWaterDepth returns DEEP_WATER constant in that case, which is too large for our needs.
|
||||
if (waterDepth == DEEP_WATER)
|
||||
waterDepth = QUAD_MAX_WATER_HEIGHT;
|
||||
|
||||
if (waterDepth <= QUAD_MAX_WATER_HEIGHT)
|
||||
{
|
||||
bool isWater = TestEnvironment(ENV_FLAG_WATER, quadItem);
|
||||
|
||||
if (quad->Velocity != 0)
|
||||
{
|
||||
auto coeff = isWater ? QUAD_WATER_VEL_COEFFICIENT : QUAD_SWAMP_VEL_COEFFICIENT;
|
||||
quad->Velocity -= std::copysign(quad->Velocity * ((waterDepth / QUAD_MAX_WATER_HEIGHT) / coeff), quad->Velocity);
|
||||
|
||||
if (GenerateInt(0, 32) > 28)
|
||||
SoundEffect(SFX_TR4_LARA_WADE, &PHD_3DPOS(quadItem->Pose.Position), SoundEnvironment::Land, isWater ? 0.8f : 0.7f);
|
||||
|
||||
if (isWater)
|
||||
TEN::Effects::TriggerSpeedboatFoam(quadItem, Vector3(0, -waterDepth / 2.0f, QUAD_BACK));
|
||||
}
|
||||
|
||||
if (quad->TurnRate != 0)
|
||||
{
|
||||
auto coeff = isWater ? QUAD_WATER_TURN_COEFFICIENT : QUAD_SWAMP_TURN_COEFFICIENT;
|
||||
quad->TurnRate -= quad->TurnRate * ((waterDepth / QUAD_MAX_WATER_HEIGHT) / coeff);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
laraItem->Animation.TargetState = QUAD_STATE_FALL_OFF;
|
||||
laraItem->Pose.Position.y = quadItem->Pose.Position.y + 700;
|
||||
|
@ -970,6 +1008,7 @@ static void AnimateQuadBike(ItemInfo* laraItem, ItemInfo* quadItem, int collide,
|
|||
QuadbikeExplode(laraItem, quadItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int QuadUserControl(ItemInfo* quadItem, int height, int* pitch)
|
||||
|
@ -1222,7 +1261,7 @@ void QuadBikeCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll
|
|||
|
||||
static void TriggerQuadExhaustSmoke(int x, int y, int z, short angle, int speed, int moving)
|
||||
{
|
||||
auto* spark = &Sparks[GetFreeSpark()];
|
||||
auto* spark = GetFreeParticle();
|
||||
|
||||
spark->on = true;
|
||||
spark->sR = 0;
|
||||
|
@ -1270,7 +1309,7 @@ static void TriggerQuadExhaustSmoke(int x, int y, int z, short angle, int speed,
|
|||
else
|
||||
spark->flags = SP_SCALE | SP_DEF | SP_EXPDEF;
|
||||
|
||||
spark->def = Objects[ID_DEFAULT_SPRITES].meshIndex;
|
||||
spark->spriteIndex = Objects[ID_DEFAULT_SPRITES].meshIndex;
|
||||
spark->scalar = 2;
|
||||
spark->gravity = -(GetRandomControl() & 3) - 4;
|
||||
spark->maxYvel = -(GetRandomControl() & 7) - 8;
|
||||
|
@ -1338,12 +1377,12 @@ bool QuadBikeControl(ItemInfo* laraItem, CollisionInfo* coll)
|
|||
else if (quad->Pitch > 0xA000)
|
||||
quad->Pitch = 0xA000;
|
||||
|
||||
SoundEffect(SFX_TR3_QUADBIKE_MOVE, &quadItem->Pose, SoundEnvironment::Land, 0.5f + (float)abs(quad->Pitch) / (float)MAX_VELOCITY);
|
||||
SoundEffect(SFX_TR3_VEHICLE_QUADBIKE_MOVE, &quadItem->Pose, SoundEnvironment::Land, 0.5f + (float)abs(quad->Pitch) / (float)MAX_VELOCITY);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (drive != -1)
|
||||
SoundEffect(SFX_TR3_QUADBIKE_IDLE, &quadItem->Pose);
|
||||
SoundEffect(SFX_TR3_VEHICLE_QUADBIKE_IDLE, &quadItem->Pose);
|
||||
|
||||
quad->Pitch = 0;
|
||||
}
|
||||
|
@ -1388,7 +1427,7 @@ bool QuadBikeControl(ItemInfo* laraItem, CollisionInfo* coll)
|
|||
{
|
||||
if (quadItem->Pose.Position.y == quadItem->Floor)
|
||||
{
|
||||
ExplodingDeath(lara->ItemNumber, 0xffffffff, 1);
|
||||
ExplodingDeath(lara->ItemNumber, ALL_JOINT_BITS, 1);
|
||||
laraItem->HitPoints = 0;
|
||||
laraItem->Flags |= ONESHOT;
|
||||
QuadbikeExplode(laraItem, quadItem);
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "Specific/input.h"
|
||||
#include "Specific/level.h"
|
||||
#include "Specific/setup.h"
|
||||
#include "Renderer/Renderer11Enums.h"
|
||||
|
||||
#define RBOAT_SLIP 10
|
||||
#define RBOAT_SIDE_SLIP 30
|
||||
|
@ -796,7 +797,7 @@ void RubberBoatAnimation(ItemInfo* laraItem, ItemInfo* rBoatItem, int collide)
|
|||
|
||||
static void TriggerRubberBoatMist(long x, long y, long z, long velocity, short angle, long snow)
|
||||
{
|
||||
auto* sptr = &Sparks[GetFreeSpark()];
|
||||
auto* sptr = GetFreeParticle();
|
||||
|
||||
sptr->on = 1;
|
||||
sptr->sR = 0;
|
||||
|
@ -819,7 +820,7 @@ static void TriggerRubberBoatMist(long x, long y, long z, long velocity, short a
|
|||
sptr->colFadeSpeed = 4 + (GetRandomControl() & 3);
|
||||
sptr->fadeToBlack = 12 - (snow * 8);
|
||||
sptr->sLife = sptr->life = (GetRandomControl() & 3) + 20;
|
||||
sptr->transType = TransTypeEnum::COLADD;
|
||||
sptr->blendMode = BLEND_MODES::BLENDMODE_ADDITIVE;
|
||||
sptr->extras = 0;
|
||||
sptr->dynamic = -1;
|
||||
|
||||
|
@ -846,7 +847,7 @@ static void TriggerRubberBoatMist(long x, long y, long z, long velocity, short a
|
|||
else
|
||||
sptr->flags = SP_SCALE | SP_DEF | SP_EXPDEF;
|
||||
|
||||
sptr->def = Objects[ID_EXPLOSION_SPRITES].meshIndex;
|
||||
sptr->spriteIndex = Objects[ID_EXPLOSION_SPRITES].meshIndex;
|
||||
|
||||
if (!snow)
|
||||
{
|
||||
|
@ -1032,9 +1033,9 @@ void RubberBoatControl(short itemNumber)
|
|||
rBoat->Pitch += ((pitch - rBoat->Pitch) / 4);
|
||||
|
||||
if (rBoatItem->Animation.Velocity > 8)
|
||||
SoundEffect(SFX_TR3_RUBBERBOAT_MOVING, &rBoatItem->Pose, SoundEnvironment::Land, 0.5f + (float)abs(rBoat->Pitch) / (float)RBOAT_MAX_VELOCITY);
|
||||
SoundEffect(SFX_TR3_VEHICLE_RUBBERBOAT_MOVING, &rBoatItem->Pose, SoundEnvironment::Land, 0.5f + (float)abs(rBoat->Pitch) / (float)RBOAT_MAX_VELOCITY);
|
||||
else if (drive)
|
||||
SoundEffect(SFX_TR3_RUBBERBOAT_IDLE, &rBoatItem->Pose, SoundEnvironment::Land, 0.5f + (float)abs(rBoat->Pitch) / (float)RBOAT_MAX_VELOCITY);
|
||||
SoundEffect(SFX_TR3_VEHICLE_RUBBERBOAT_IDLE, &rBoatItem->Pose, SoundEnvironment::Land, 0.5f + (float)abs(rBoat->Pitch) / (float)RBOAT_MAX_VELOCITY);
|
||||
|
||||
if (lara->Vehicle != itemNumber)
|
||||
return;
|
||||
|
|
|
@ -102,7 +102,8 @@ enum UPVState
|
|||
// TODO
|
||||
enum UPVAnim
|
||||
{
|
||||
UPV_ANIM_DEATH = 0,
|
||||
UPV_ANIM_DEATH_MOVING = 0,
|
||||
UPV_ANIM_DEATH = 1,
|
||||
|
||||
UPV_ANIM_IDLE = 5,
|
||||
|
||||
|
@ -172,7 +173,7 @@ static void FireUPVHarpoon(ItemInfo* laraItem, ItemInfo* UPVItem)
|
|||
|
||||
AddActiveItem(itemNumber);
|
||||
|
||||
SoundEffect(SFX_TR4_LARA_HARPOON_FIRE_WATER, &laraItem->Pose, SoundEnvironment::Always);
|
||||
SoundEffect(SFX_TR4_HARPOON_FIRE_UNDERWATER, &laraItem->Pose, SoundEnvironment::Always);
|
||||
|
||||
Statistics.Game.AmmoUsed++;
|
||||
UPV->HarpoonLeft = !UPV->HarpoonLeft;
|
||||
|
@ -181,7 +182,7 @@ static void FireUPVHarpoon(ItemInfo* laraItem, ItemInfo* UPVItem)
|
|||
|
||||
static void TriggerUPVMist(long x, long y, long z, long velocity, short angle)
|
||||
{
|
||||
auto* sptr = &Sparks[GetFreeSpark()];
|
||||
auto* sptr = GetFreeParticle();
|
||||
|
||||
sptr->on = 1;
|
||||
sptr->sR = 0;
|
||||
|
@ -195,7 +196,7 @@ static void TriggerUPVMist(long x, long y, long z, long velocity, short angle)
|
|||
sptr->colFadeSpeed = 4 + (GetRandomControl() & 3);
|
||||
sptr->fadeToBlack = 12;
|
||||
sptr->sLife = sptr->life = (GetRandomControl() & 3) + 20;
|
||||
sptr->transType = TransTypeEnum::COLADD;
|
||||
sptr->blendMode = BLEND_MODES::BLENDMODE_ADDITIVE;
|
||||
sptr->extras = 0;
|
||||
sptr->dynamic = -1;
|
||||
|
||||
|
@ -630,8 +631,8 @@ static void UPVControl(ItemInfo* laraItem, ItemInfo* UPVItem)
|
|||
|
||||
//sub->Flags &= ~UPV_CONTROL; having this here causes the UPV glitch, moving it directly to the states' code is better
|
||||
|
||||
StopSoundEffect(SFX_TR3_UPV_LOOP);
|
||||
SoundEffect(SFX_TR3_UPV_STOP, (PHD_3DPOS*)&UPVItem->Pose.Position.x, SoundEnvironment::Always);
|
||||
StopSoundEffect(SFX_TR3_VEHICLE_UPV_LOOP);
|
||||
SoundEffect(SFX_TR3_VEHICLE_UPV_STOP, (PHD_3DPOS*)&UPVItem->Pose.Position.x, SoundEnvironment::Always);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -656,7 +657,7 @@ static void UPVControl(ItemInfo* laraItem, ItemInfo* UPVItem)
|
|||
UPVItem->Pose.Orientation.x += ANGLE(1.0f);
|
||||
|
||||
if (frame == MOUNT_SURFACE_SOUND_FRAME)
|
||||
SoundEffect(SFX_TR3_UPV_LOOP, (PHD_3DPOS*)&UPVItem->Pose.Position.x, SoundEnvironment::Always);
|
||||
SoundEffect(SFX_TR3_VEHICLE_UPV_LOOP, (PHD_3DPOS*)&UPVItem->Pose.Position.x, SoundEnvironment::Always);
|
||||
|
||||
if (frame == MOUNT_SURFACE_CONTROL_FRAME)
|
||||
UPV->Flags |= UPV_CONTROL;
|
||||
|
@ -665,7 +666,7 @@ static void UPVControl(ItemInfo* laraItem, ItemInfo* UPVItem)
|
|||
else if (anim == UPV_ANIM_MOUNT_UNDERWATER)
|
||||
{
|
||||
if (frame == MOUNT_UNDERWATER_SOUND_FRAME)
|
||||
SoundEffect(SFX_TR3_UPV_LOOP, (PHD_3DPOS*)&UPVItem->Pose.Position.x, SoundEnvironment::Always);
|
||||
SoundEffect(SFX_TR3_VEHICLE_UPV_LOOP, (PHD_3DPOS*)&UPVItem->Pose.Position.x, SoundEnvironment::Always);
|
||||
|
||||
if (frame == MOUNT_UNDERWATER_CONTROL_FRAME)
|
||||
UPV->Flags |= UPV_CONTROL;
|
||||
|
@ -760,7 +761,8 @@ static void UPVControl(ItemInfo* laraItem, ItemInfo* UPVItem)
|
|||
break;
|
||||
|
||||
case UPV_STATE_DEATH:
|
||||
if (anim == UPV_ANIM_DEATH && (frame == DEATH_FRAME_1 || frame == DEATH_FRAME_2))
|
||||
if ((anim == UPV_ANIM_DEATH || anim == UPV_ANIM_DEATH_MOVING) &&
|
||||
(frame == DEATH_FRAME_1 || frame == DEATH_FRAME_2))
|
||||
{
|
||||
auto vec = Vector3Int();
|
||||
GetLaraJointPosition(&vec, LM_HIPS);
|
||||
|
@ -958,8 +960,8 @@ bool UPVControl(ItemInfo* laraItem, CollisionInfo* coll)
|
|||
|
||||
UPV->Flags |= UPV_SURFACE;
|
||||
}
|
||||
|
||||
else if ((waterHeight - UPVItem->Pose.Position.y) >= -SURFACE_DIST && waterHeight != NO_HEIGHT)
|
||||
else if ((waterHeight - UPVItem->Pose.Position.y) >= -SURFACE_DIST && waterHeight != NO_HEIGHT &&
|
||||
(laraItem->Pose.Position.y - probe.Position.Ceiling) >= CLICK(1))
|
||||
{
|
||||
UPVItem->Pose.Position.y = waterHeight + SURFACE_DIST;
|
||||
|
||||
|
@ -971,7 +973,6 @@ bool UPVControl(ItemInfo* laraItem, CollisionInfo* coll)
|
|||
|
||||
UPV->Flags |= UPV_SURFACE;
|
||||
}
|
||||
|
||||
else
|
||||
UPV->Flags &= ~UPV_SURFACE;
|
||||
|
||||
|
@ -1031,7 +1032,7 @@ bool UPVControl(ItemInfo* laraItem, CollisionInfo* coll)
|
|||
BackgroundCollision(laraItem, UPVItem);
|
||||
|
||||
if (UPV->Flags & UPV_CONTROL)
|
||||
SoundEffect(SFX_TR3_UPV_LOOP, (PHD_3DPOS*)&UPVItem->Pose.Position.x, SoundEnvironment::Always, 1.0f + (float)UPVItem->Animation.Velocity / 96.0f);
|
||||
SoundEffect(SFX_TR3_VEHICLE_UPV_LOOP, (PHD_3DPOS*)&UPVItem->Pose.Position.x, SoundEnvironment::Always, 1.0f + (float)UPVItem->Animation.Velocity / 96.0f);
|
||||
|
||||
UPVItem->Animation.AnimNumber = Objects[ID_UPV].animIndex + (laraItem->Animation.AnimNumber - Objects[ID_UPV_LARA_ANIMS].animIndex);
|
||||
UPVItem->Animation.FrameNumber = g_Level.Anims[UPVItem->Animation.AnimNumber].frameBase + (laraItem->Animation.FrameNumber - g_Level.Anims[laraItem->Animation.AnimNumber].frameBase);
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue