Merge branch 'master' into very_experimental_input_stuff

This commit is contained in:
Sezz 2022-08-08 00:52:33 +10:00
commit 27e7c49b25
38 changed files with 978 additions and 336 deletions

1
.gitignore vendored
View file

@ -24,3 +24,4 @@ packages/
*.wav
*.trc
*.str
*.ten

12
Documentation/Changes.txt Normal file
View file

@ -0,0 +1,12 @@
Version 1.0.1
=============
- Fixed rope transparency.
- Fixed incorrect polerope grabbing.
- Fixed camera behaviour with pushable blocks.
- Fixed minecart unduck on inclines.
Version 1.0
===========
First beta release.

View file

@ -147,11 +147,11 @@
<td class="summary">Play sound effect</td>
</tr>
<tr>
<td class="name" ><a href="#KeyHeld">KeyHeld(action)</a></td>
<td class="name" ><a href="#KeyIsHeld">KeyIsHeld(action)</a></td>
<td class="summary">Check if particular action key is held</td>
</tr>
<tr>
<td class="name" ><a href="#KeyHit">KeyHit(action)</a></td>
<td class="name" ><a href="#KeyIsHit">KeyIsHit(action)</a></td>
<td class="summary">Check if particular action key was hit (once)</td>
</tr>
<tr>
@ -542,8 +542,8 @@ To be used with <a href="../2 classes/Strings.DisplayString.html#DisplayString:G
</dd>
<dt>
<a name = "KeyHeld"></a>
<strong>KeyHeld(action)</strong>
<a name = "KeyIsHeld"></a>
<strong>KeyIsHeld(action)</strong>
</dt>
<dd>
Check if particular action key is held
@ -563,8 +563,8 @@ To be used with <a href="../2 classes/Strings.DisplayString.html#DisplayString:G
</dd>
<dt>
<a name = "KeyHit"></a>
<strong>KeyHit(action)</strong>
<a name = "KeyIsHit"></a>
<strong>KeyIsHit(action)</strong>
</dt>
<dd>
Check if particular action key was hit (once)

View file

@ -1,5 +1,7 @@
-- Place in this LUA script all the levels of your game
-- Title is mandatory and must be the first level
-- Title is mandatory and must be the first level.
-- Shorten some of the internal data types.
local Flow = TEN.Flow
local Level = Flow.Level
@ -10,10 +12,18 @@ local InvID = Flow.InvID
local RotationAxis = Flow.RotationAxis
local ItemAction = Flow.ItemAction
Flow.SetIntroImagePath("Screens\\Main.png")
Flow.SetTitleScreenImagePath("Screens\\Title.jpg")
-- These variables are unused for now.
Flow.SetIntroImagePath("Screens\\main.jpg")
Flow.SetTitleScreenImagePath("Screens\\main.jpg")
-- Flow.SetFarView sets global far view distance in blocks.
-- It will be overwritten by level.farView value, if it is specified.
Flow.SetFarView(20)
--------------------------------------------------
-- Title level
title = Level.new()
@ -25,7 +35,10 @@ title.loadScreenFile = "Screens\\Main.png"
Flow.AddLevel(title)
--------------------------------------------------
-- First test level
test = Level.new()
test.nameKey = "level_test"
@ -33,13 +46,20 @@ test.scriptFile = "Scripts\\TestLevel.lua"
test.ambientTrack = "108"
test.levelFile = "Data\\TestLevel.ten"
test.loadScreenFile = "Screens\\rome.jpg"
-- 0 is no weather, 1 is rain, 2 is snow.
-- Strength varies from 0 to 1 (floating-point value, e.g. 0.5 means half-strength).
test.weather = 0
test.weatherStrength = 1
test.horizon = true
test.farView = 20
test.layer1 = Flow.SkyLayer.new(Color.new(255, 0, 0), 15)
test.fog = Flow.Fog.new(Color.new(0, 0, 0), 12, 20)
-- Presets for inventory item placement.
test.objects = {
InventoryItem.new(
"tut1_ba_cartouche1",

View file

@ -1,5 +1,117 @@
-- Test level script file
local Util = require("Util")
Util.ShortenTENCalls()
LevelFuncs.OnLoad = function() end
LevelFuncs.OnSave = function() end
LevelFuncs.OnControlPhase = function() end
LevelFuncs.OnEnd = function() end
-- An example function which prints a string and leaves it on screen for 1 second.
-- Argument should be typed in TE trigger manager window's argument text field.
LevelFuncs.PrintText = function(Triggerer, Argument)
local TestText = DisplayString(Argument, 100, 100, Color.new(250,250,250))
ShowString(TestText, 1)
end
-- Another example function which emits rotating electric halo around object,
-- which triggered it.
local currentX = 0.0
local currentY = 0.0
LevelFuncs.EmitHaloOnActionPush = function(Triggerer)
-- This is a list of all possible keys which can be checked for their pushed/not pushed state.
-- Later we will move them to separate internal file or make them internal TEN constants.
local Keys =
{
Forward = 0,
Back = 1,
Left = 2,
Right = 3,
Crouch = 4,
Sprint = 5,
Walk = 6,
Jump = 7,
Action = 8,
Draw = 9,
Flare = 10,
Look = 11,
Roll = 12,
Inventory = 13,
Pause = 14,
StepLeft = 15,
StepRight = 16
}
-- First argument which is passed to function that is triggered from TE volumes is
-- always an object which triggered it (except cases when triggerer is static mesh or
-- flyby camera). We can directly use Triggerer argument to get some properties from
-- it. In this case, we get position of a root joint (in case of Lara, it is her hips).
local pos = Triggerer:GetJointPosition(0)
-- math.random() is an internal Lua method which returns a value between 2 specified limits,
-- in our case something between 200 and 255. We use it to vary halo intensity a bit.
local color = math.random(200, 255)
local velocity = Vec3(0, 0, 0) -- No velocity
-- Again, we can use velocity to get some value between 60 and 80 to vary rotation rate of
-- a spawned halo particle.
local rot = math.random(60, 80)
-- circleLength is standard mathematical constant for circle length which is later used to
-- get sin/cos value to rotate light and particle around an object.
local circleLength = 3.14 * 2.0
-- Progress currentX and currentY variables to change current X and Y positions of the halo.
currentX = currentX + 0.2
currentY = currentY + 0.1
-- Here we clamp currentX and currentY values to max circle length, because sin/cos operations
-- can't operate out of circle length range.
if (currentX > circleLength) then
currentX = currentX - circleLength;
end
if (currentY > circleLength) then
currentY = currentY - circleLength;
end
local horizontalAmplitude = 384 -- 3 clicks height, where effect wanders about.
local haloRotationDistance = 256 -- rotate on distance 2 clicks around object.
-- Calculate relative offset of a halo using simple sin/cos functions.
local offsetX = math.cos(currentX) * haloRotationDistance
local offsetZ = math.sin(currentX) * haloRotationDistance
local offsetY = math.sin(currentY) * horizontalAmplitude
-- Add relative offsets to joint position.
pos.x = pos.x + offsetX
pos.y = pos.y + offsetY
pos.z = pos.z + offsetZ
-- Play electrical sound.
Misc.PlaySound(197, pos)
-- Emit particle and light. Look into manual for list of arguments.
Effects.EmitParticle(pos, velocity, 2, 1, rot, Color.new(color * 0.5, color * 0.5, color), Color.new(color * 0.2, color * 0.1, color), 2, 16, 64, 1, false, false)
Effects.EmitLight(pos, Color.new(color * 0.5, color * 0.5, color), 7)
end

View file

@ -14,6 +14,7 @@ Global
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{15AB0220-541C-4DA1-94EB-ED3C47E4582E}.Debug|x64.ActiveCfg = Debug|Win32
{15AB0220-541C-4DA1-94EB-ED3C47E4582E}.Debug|x64.Build.0 = Debug|Win32
{15AB0220-541C-4DA1-94EB-ED3C47E4582E}.Debug|x86.ActiveCfg = Debug|Win32
{15AB0220-541C-4DA1-94EB-ED3C47E4582E}.Debug|x86.Build.0 = Debug|Win32
{15AB0220-541C-4DA1-94EB-ED3C47E4582E}.Release|x64.ActiveCfg = Release|Win32

View file

@ -4,6 +4,7 @@
#include "Flow/ScriptInterfaceFlowHandler.h"
#include "Game/collision/collide_room.h"
#include "Game/control/control.h"
#include "Game/control/volume.h"
#include "Game/items.h"
#include "Game/Lara/lara.h"
#include "Game/Lara/lara_collide.h"
@ -24,6 +25,7 @@
#include "Objects/TR4/Vehicles/jeep.h"
#include "Objects/TR4/Vehicles/motorbike.h"
using namespace TEN::Control::Volumes;
using namespace TEN::Input;
using namespace TEN::Renderer;
@ -77,6 +79,8 @@ bool HandleLaraVehicle(ItemInfo* item, CollisionInfo* coll)
if (lara->Vehicle != NO_ITEM)
{
TestVolumes(lara->Vehicle);
switch (g_Level.Items[lara->Vehicle].ObjectNumber)
{
case ID_QUAD:

View file

@ -171,7 +171,6 @@ void lara_as_pushable_push(ItemInfo* item, CollisionInfo* coll)
Camera.targetAngle = ANGLE(35.0f);
Camera.targetElevation = -ANGLE(25.0f);
Camera.flags = CF_FOLLOW_CENTER;
Camera.laraNode = LM_TORSO;
}
// State: LS_PUSHABLE_PULL (37)
@ -186,7 +185,6 @@ void lara_as_pushable_pull(ItemInfo* item, CollisionInfo* coll)
Camera.targetAngle = ANGLE(35.0f);
Camera.targetElevation = -ANGLE(25.0f);
Camera.flags = CF_FOLLOW_CENTER;
Camera.laraNode = LM_TORSO;
}
// State: LS_PUSHABLE_GRAB (38)

View file

@ -445,7 +445,7 @@ void lara_as_slopeclimb(ItemInfo* item, CollisionInfo* coll)
else
item->Pose.Orientation.x++;
Camera.flags = 1;
Camera.flags = CF_FOLLOW_CENTER;
if (Camera.type != CameraType::Chase)
return;
@ -464,7 +464,7 @@ void lara_as_slopefall(ItemInfo* item, CollisionInfo* coll)
else
item->Pose.Orientation.x++;
Camera.flags = 1;
Camera.flags = CF_FOLLOW_CENTER;
if (Camera.type != CameraType::Chase)
return;
@ -629,7 +629,7 @@ void lara_as_slopeclimbup(ItemInfo* item, CollisionInfo* coll)
else
item->Pose.Orientation.x++;
Camera.flags = 1;
Camera.flags = CF_FOLLOW_CENTER;
if (Camera.type != CameraType::Chase)
return; // If camera mode isn't chase (0) then don't change camera angles.
@ -660,7 +660,7 @@ void lara_as_slopeclimbdown(ItemInfo* item, CollisionInfo* coll)
else
item->Pose.Orientation.x++;
Camera.flags = 1;
Camera.flags = CF_FOLLOW_CENTER;
if (Camera.type != CameraType::Chase)
return;
@ -695,7 +695,7 @@ void lara_as_sclimbstart(ItemInfo* item, CollisionInfo* coll)
if (frac > 1.0f)
frac = 1.0f;
Camera.flags = 1;
Camera.flags = CF_FOLLOW_CENTER;
int distance = TestLaraWall(item, 0, SECTOR(1.5f), 0) ? SECTOR(1) : CLICK(6.5f);
@ -717,7 +717,7 @@ void lara_as_sclimbstart(ItemInfo* item, CollisionInfo* coll)
}
else// if (item->animNumber == LA_OVERHANG_MONKEY_SLOPE_CONCAVE)
{
//Camera.flags = 1;
//Camera.flags = CF_FOLLOW_CENTER;
Camera.targetElevation = -ANGLE(11.25f);
Camera.targetDistance = CLICK(6.5f);
Camera.speed = 15;
@ -736,7 +736,7 @@ void lara_as_sclimbstop(ItemInfo* item, CollisionInfo* coll)
// Following camera effect during the slope to underlying monkey transition.
if (item->Animation.AnimNumber == LA_OVERHANG_SLOPE_MONKEY_CONVEX)
{
Camera.flags = 1;
Camera.flags = CF_FOLLOW_CENTER;
Camera.targetDistance = CLICK(6.5f);
Camera.targetElevation = ANGLE(11.25f);
Camera.targetspeed = 15;
@ -751,7 +751,7 @@ void lara_as_sclimbstop(ItemInfo* item, CollisionInfo* coll)
if (frac > 1.0f)
frac = 1.0f;
Camera.flags = 1;
Camera.flags = CF_FOLLOW_CENTER;
if (item->Animation.FrameNumber < g_Level.Anims[item->Animation.AnimNumber].frameEnd)
{

View file

@ -142,7 +142,7 @@ void InitialiseCamera()
Camera.numberFrames = 1;
Camera.type = CameraType::Chase;
Camera.speed = 1;
Camera.flags = CF_FOLLOW_CENTER;
Camera.flags = CF_NONE;
Camera.bounce = 0;
Camera.number = -1;
Camera.fixedCamera = false;
@ -1533,20 +1533,24 @@ void CalculateCamera()
Camera.target.roomNumber = item->RoomNumber;
Camera.target.y = y;
auto shift = (bounds->X1 + bounds->X2 + bounds->Z1 + bounds->Z2) / 4;
x = item->Pose.Position.x + shift * phd_sin(item->Pose.Orientation.y);
z = item->Pose.Position.z + shift * phd_cos(item->Pose.Orientation.y);
x = item->Pose.Position.x;
z = item->Pose.Position.z;
if (Camera.flags == CF_FOLLOW_CENTER) //Troye Aug. 7th 2022
{
auto shift = (bounds->Z1 + bounds->Z2) / 2;
x += shift * phd_sin(item->Pose.Orientation.y);
z += shift * phd_cos(item->Pose.Orientation.y);
}
Camera.target.x = x;
Camera.target.z = z;
if (item->ObjectNumber == ID_LARA)
{
// CF_FOLLOW_CENTER sets target on the item, ConfirmCameraTargetPos overrides this target,
// hence the flag check. Troye Aug. 7th 2022
if (item->IsLara() && Camera.flags != CF_FOLLOW_CENTER)
ConfirmCameraTargetPos();
x = Camera.target.x;
y = Camera.target.y;
z = Camera.target.z;
}
if (fixedCamera == Camera.fixedCamera)
{
@ -2058,51 +2062,65 @@ void UpdateFadeScreenAndCinematicBars()
void HandleOptics(ItemInfo* item)
{
auto* lara = GetLaraInfo(item);
bool breakOptics = true;
if (!(TrInput & IN_LOOK) || UseSpotCam || TrackCameraInit ||
((item->Animation.ActiveState != LS_IDLE || item->Animation.AnimNumber != LA_STAND_IDLE) &&
(!lara->Control.IsLow || TrInput & IN_CROUCH || item->Animation.TargetState != LS_CROUCH_IDLE || item->Animation.AnimNumber != LA_CROUCH_IDLE)))
if (!LaserSight && BinocularOn) // Imitate pushing look key in binocular mode
{
if (BinocularRange == 0)
{
if (UseSpotCam || TrackCameraInit)
ClearAction(In::Look);
}
else
{
// TODO: Adapt this.
// If any input but optic controls (directions + action), immediately exit binoculars mode.
//if (TrInput != IN_NONE && ((TrInput & ~IN_OPTIC_CONTROLS) != IN_NONE))
// BinocularRange = 0;
if (LaserSight)
{
BinocularRange = 0;
BinocularOn = false;
LaserSight = false;
Camera.type = BinocularOldCamera;
Camera.bounce = 0;
AlterFOV(ANGLE(80.0f));
item->MeshBits = ALL_JOINT_BITS;
lara->Inventory.IsBusy = false;
ResetLaraFlex(item);
}
}
TrInput |= IN_LOOK;
DbInput = 0;
}
else if (!BinocularRange)
// We are standing, can use optics.
if (LaraItem->Animation.ActiveState == LS_IDLE || LaraItem->Animation.AnimNumber == LA_STAND_IDLE)
breakOptics = false;
// We are crouching, can use optics.
if ((Lara.Control.IsLow || TrInput & IN_CROUCH) &&
(LaraItem->Animation.TargetState == LS_CROUCH_IDLE || LaraItem->Animation.AnimNumber == LA_CROUCH_IDLE))
breakOptics = false;
// TODO: Translate to input action.
// If any input but optic controls (directions + action), immediately exit optics.
//if ((TrInput & ~IN_OPTIC_CONTROLS) != IN_NONE)
// breakOptics = true;
// If lasersight, and no look is pressed, exit optics.
if (LaserSight && !(TrInput & IN_LOOK))
breakOptics = true;
if (!LaserSight && !breakOptics && (TrInput == IN_LOOK)) // Engage lasersight, if available.
{
if (lara->Control.HandStatus == HandStatus::WeaponReady &&
((lara->Control.Weapon.GunType == LaraWeaponType::Revolver && lara->Weapons[(int)LaraWeaponType::Revolver].HasLasersight) ||
lara->Control.Weapon.GunType == LaraWeaponType::HK ||
(lara->Control.Weapon.GunType == LaraWeaponType::Crossbow && lara->Weapons[(int)LaraWeaponType::Crossbow].HasLasersight)))
if (Lara.Control.HandStatus == HandStatus::WeaponReady &&
(Lara.Control.Weapon.GunType == LaraWeaponType::HK ||
(Lara.Control.Weapon.GunType == LaraWeaponType::Revolver && Lara.Weapons[(int)LaraWeaponType::Revolver].HasLasersight) ||
(Lara.Control.Weapon.GunType == LaraWeaponType::Crossbow && Lara.Weapons[(int)LaraWeaponType::Crossbow].HasLasersight)))
{
BinocularRange = 128;
BinocularOldCamera = Camera.oldType;
BinocularOn = true;
LaserSight = true;
lara->Inventory.IsBusy = true;
Lara.Inventory.IsBusy = true;
return;
}
}
}
if (!breakOptics)
return;
// Nothing to process, exit.
if (!BinocularOn && !LaserSight)
return;
BinocularRange = 0;
BinocularOn = false;
LaserSight = false;
Camera.type = BinocularOldCamera;
Camera.bounce = 0;
AlterFOV(ANGLE(80.0f));
LaraItem->MeshBits = ALL_JOINT_BITS;
Lara.Inventory.IsBusy = false;
ResetLaraFlex(LaraItem);
TrInput &= ~IN_LOOK;
}

View file

@ -43,6 +43,7 @@ struct CAMERA_INFO
enum CAMERA_FLAGS
{
CF_NONE = 0,
CF_FOLLOW_CENTER = 1,
CF_NO_CHUNKY = 2,
CF_CHASE_OBJECT = 3,

View file

@ -420,7 +420,7 @@ bool AlignLaraPosition(Vector3Int* vec, ItemInfo* item, ItemInfo* laraItem)
Vector3 newPos = item->Pose.Position.ToVector3() + pos;
int height = GetCollision(newPos.x, newPos.y, newPos.z, laraItem->RoomNumber).Position.Floor;
if (abs(height - laraItem->Pose.Position.y) <= CLICK(2))
if ((laraItem->Pose.Position.y - height) <= CLICK(2))
{
laraItem->Pose.Position.x = newPos.x;
laraItem->Pose.Position.y = newPos.y;

View file

@ -641,6 +641,8 @@ void UpdateShatters()
SmashedMesh[SmashedMeshCount]->pos.Position.z,
SmashedMeshRoom[SmashedMeshCount], true);
TestVolumes(SmashedMeshRoom[SmashedMeshCount], SmashedMesh[SmashedMeshCount]);
floor->Stopper = false;
SmashedMesh[SmashedMeshCount] = 0;
} while (SmashedMeshCount != 0);

View file

@ -15,7 +15,6 @@ using TEN::Renderer::g_Renderer;
namespace TEN::Control::Volumes
{
constexpr auto CAM_SIZE = 32;
int CurrentCollidedVolume;
@ -30,9 +29,29 @@ namespace TEN::Control::Volumes
{
auto* volume = &room->triggerVolumes[i];
if ((volume->Activators & activatorType) != activatorType)
if (volume->EventSetIndex == NO_EVENT_SET)
continue;
auto* set = &g_Level.EventSets[volume->EventSetIndex];
if ((set->Activators & activatorType) != activatorType)
continue;
// Determine what to do if volume is busy with another triggerer
if (!std::holds_alternative<nullptr_t>(volume->Triggerer) && volume->Triggerer != triggerer)
{
if (GameTimer - volume->Timeout > VOLUME_BUSY_TIMEOUT)
{
// We are past the busy timeout, reset current triggerer and volume status.
volume->Triggerer = nullptr;
volume->Status = TriggerStatus::Outside;
}
else
// We are in the same frame, triggerer is busy, leave it alone.
continue;
}
bool contains = false;
switch (volume->Type)
@ -56,24 +75,39 @@ namespace TEN::Control::Volumes
if (volume->Status == TriggerStatus::Outside)
{
volume->Triggerer = triggerer;
volume->Timeout = GameTimer;
volume->Status = TriggerStatus::Entering;
if (!volume->OnEnter.empty())
g_GameScript->ExecuteFunction(volume->OnEnter, triggerer);
if (!set->OnEnter.Function.empty() && set->OnEnter.CallCounter != 0)
{
g_GameScript->ExecuteFunction(set->OnEnter.Function, triggerer, set->OnEnter.Argument);
if (set->OnEnter.CallCounter != NO_CALL_COUNTER)
set->OnEnter.CallCounter--;
}
}
else
{
volume->Status = TriggerStatus::Inside;
if (!volume->OnInside.empty())
g_GameScript->ExecuteFunction(volume->OnInside, triggerer);
if (!set->OnInside.Function.empty() && set->OnInside.CallCounter != 0)
{
g_GameScript->ExecuteFunction(set->OnInside.Function, triggerer, set->OnInside.Argument);
if (set->OnInside.CallCounter != NO_CALL_COUNTER)
set->OnInside.CallCounter--;
}
}
}
else
{
if (volume->Status == TriggerStatus::Inside)
{
volume->Triggerer = nullptr;
volume->Status = TriggerStatus::Leaving;
if (!volume->OnLeave.empty())
g_GameScript->ExecuteFunction(volume->OnLeave, triggerer);
if (!set->OnLeave.Function.empty() && set->OnLeave.CallCounter != 0)
{
g_GameScript->ExecuteFunction(set->OnLeave.Function, triggerer, set->OnLeave.Argument);
if (set->OnLeave.CallCounter != NO_CALL_COUNTER)
set->OnLeave.CallCounter--;
}
}
else
volume->Status = TriggerStatus::Outside;

View file

@ -4,6 +4,11 @@
#include "Specific/setup.h"
#include "Renderer/Renderer11.h"
constexpr auto NO_EVENT_SET = -1;
constexpr auto NO_CALL_COUNTER = -1;
constexpr auto VOLUME_BUSY_TIMEOUT = 10;
enum class TriggerStatus
{
Outside,
@ -32,21 +37,18 @@ enum TriggerVolumeActivators
struct TriggerVolume
{
TriggerVolumeType Type;
int EventSetIndex;
Vector3 Position;
Quaternion Rotation;
Vector3 Scale; // x used as radius if type is TriggerVolumeType::Sphere.
std::string OnEnter;
std::string OnInside;
std::string OnLeave;
int Activators;
bool OneShot;
TriggerStatus Status;
BoundingOrientedBox Box;
BoundingSphere Sphere;
TriggerStatus Status = TriggerStatus::Outside;
VolumeTriggerer Triggerer = nullptr;
int Timeout = 0;
};
namespace TEN::Control::Volumes

View file

@ -7,7 +7,33 @@ struct CAMERA_INFO;
namespace TEN::Control::Volumes
{
using VolumeTriggerer = std::variant<
std::nullptr_t,
short,
MESH_INFO*,
CAMERA_INFO *>;
CAMERA_INFO*>;
enum class VolumeEventMode
{
LevelScript,
Constructor
};
struct VolumeEvent
{
VolumeEventMode Mode;
std::string Function;
std::string Argument;
int CallCounter;
};
struct VolumeEventSet
{
std::string Name;
int Activators;
VolumeEvent OnEnter;
VolumeEvent OnLeave;
VolumeEvent OnInside;
};
};

View file

@ -7,6 +7,8 @@
#include "Game/control/box.h"
#include "Game/control/flipeffect.h"
#include "Game/control/lot.h"
#include "Game/control/volume.h"
#include "Game/control/volumetriggerer.h"
#include "Game/effects/lara_fx.h"
#include "Game/effects/effects.h"
#include "Game/items.h"
@ -32,7 +34,7 @@
#include "effects/effects.h"
#include "Objects/ScriptInterfaceObjectsHandler.h"
using namespace TEN::Control::Volumes;
using namespace TEN::Effects::Lara;
using namespace TEN::Entities::Switches;
using namespace TEN::Entities::TR4;
@ -690,12 +692,10 @@ bool SaveGame::Save(int slot)
auto serializedItemsOffset = fbb.CreateVector(serializedItems);
std::vector<flatbuffers::Offset<Save::FXInfo>> serializedEffects{};
// TODO: In future, we should save only active FX, not whole array.
// This may come together with Monty's branch merge -- Lwmte, 10.07.22
std::vector<flatbuffers::Offset<Save::FXInfo>> serializedEffects{};
for (auto& effectToSerialize : EffectList)
{
Save::FXInfoBuilder serializedEffect{ fbb };
@ -717,9 +717,24 @@ bool SaveGame::Save(int slot)
auto serializedEffectOffset = serializedEffect.Finish();
serializedEffects.push_back(serializedEffectOffset);
}
auto serializedEffectsOffset = fbb.CreateVector(serializedEffects);
// Event set call counters
std::vector<flatbuffers::Offset<Save::EventSetCallCounters>> serializedEventSetCallCounters{};
for (auto& set : g_Level.EventSets)
{
Save::EventSetCallCountersBuilder serializedEventSetCallCounter{ fbb };
serializedEventSetCallCounter.add_on_enter(set.OnEnter.CallCounter);
serializedEventSetCallCounter.add_on_inside(set.OnInside.CallCounter);
serializedEventSetCallCounter.add_on_leave(set.OnLeave.CallCounter);
auto serializedEventSetCallCounterOffset = serializedEventSetCallCounter.Finish();
serializedEventSetCallCounters.push_back(serializedEventSetCallCounterOffset);
}
auto serializedEventSetCallCountersOffset = fbb.CreateVector(serializedEventSetCallCounters);
// Soundtrack playheads
auto bgmTrackData = GetSoundTrackNameAndPosition(SoundTrackType::BGM);
auto oneshotTrackData = GetSoundTrackNameAndPosition(SoundTrackType::OneShot);
@ -781,8 +796,9 @@ bool SaveGame::Save(int slot)
}
auto flybyCamerasOffset = fbb.CreateVector(flybyCameras);
// Static meshes
// Static meshes and volume states
std::vector<flatbuffers::Offset<Save::StaticMeshInfo>> staticMeshes;
std::vector<flatbuffers::Offset<Save::VolumeState>> volumeStates;
for (int i = 0; i < g_Level.Rooms.size(); i++)
{
auto* room = &g_Level.Rooms[i];
@ -790,17 +806,61 @@ bool SaveGame::Save(int slot)
for (int j = 0; j < room->mesh.size(); j++)
{
Save::StaticMeshInfoBuilder staticMesh{ fbb };
staticMesh.add_position(&Save::Vector3(room->mesh[j].pos.Position.x,
room->mesh[j].pos.Position.y,
room->mesh[j].pos.Position.z));
staticMesh.add_rotation(&Save::Vector3(room->mesh[j].pos.Orientation.x,
room->mesh[j].pos.Orientation.y,
room->mesh[j].pos.Orientation.z));
staticMesh.add_color(&Save::Vector4(room->mesh[j].color.x,
room->mesh[j].color.y,
room->mesh[j].color.z,
room->mesh[j].color.w));
staticMesh.add_flags(room->mesh[j].flags);
staticMesh.add_hit_points(room->mesh[j].HitPoints);
staticMesh.add_room_number(i);
staticMesh.add_number(j);
staticMeshes.push_back(staticMesh.Finish());
}
for (int j = 0; j < room->triggerVolumes.size(); j++)
{
Save::VolumeStateBuilder volumeState{ fbb };
auto& volume = room->triggerVolumes[j];
volumeState.add_room_number(i);
volumeState.add_number(j);
volumeState.add_position(&Save::Vector3(volume.Position.x,
volume.Position.y,
volume.Position.z));
volumeState.add_rotation(&Save::Vector4(volume.Rotation.x,
volume.Rotation.y,
volume.Rotation.z,
volume.Rotation.w));
volumeState.add_scale(&Save::Vector3(volume.Scale.x,
volume.Scale.y,
volume.Scale.z));
int triggerer = -1;
if (std::holds_alternative<short>(volume.Triggerer))
triggerer = std::get<short>(volume.Triggerer);
volumeState.add_triggerer(triggerer);
volumeState.add_state((int)volume.Status);
volumeState.add_timeout((int)volume.Timeout);
volumeStates.push_back(volumeState.Finish());
}
}
auto staticMeshesOffset = fbb.CreateVector(staticMeshes);
auto volumeStatesOffset = fbb.CreateVector(volumeStates);
// Particles
std::vector<flatbuffers::Offset<Save::ParticleInfo>> particles;
@ -1135,6 +1195,7 @@ bool SaveGame::Save(int slot)
sgb.add_flip_status(FlipStatus);
sgb.add_flip_timer(0);
sgb.add_static_meshes(staticMeshesOffset);
sgb.add_volume_states(volumeStatesOffset);
sgb.add_fixed_cameras(camerasOffset);
sgb.add_particles(particleOffset);
sgb.add_bats(batsOffset);
@ -1143,6 +1204,7 @@ bool SaveGame::Save(int slot)
sgb.add_scarabs(scarabsOffset);
sgb.add_sinks(sinksOffset);
sgb.add_flyby_cameras(flybyCamerasOffset);
sgb.add_call_counters(serializedEventSetCallCountersOffset);
if (Lara.Control.Rope.Ptr != -1)
{
@ -1151,7 +1213,6 @@ bool SaveGame::Save(int slot)
sgb.add_alternate_pendulum(alternatePendulumOffset);
}
sgb.add_script_vars(unionVecOffset);
auto sg = sgb.Finish();
@ -1234,27 +1295,63 @@ bool SaveGame::Load(int slot)
{
auto staticMesh = s->static_meshes()->Get(i);
auto room = &g_Level.Rooms[staticMesh->room_number()];
int number = staticMesh->number();
if (i >= room->mesh.size())
break;
room->mesh[number].pos.Position = Vector3Int(staticMesh->position()->x(),
staticMesh->position()->y(),
staticMesh->position()->z());
room->mesh[i].color = Vector4(staticMesh->color()->x(),
staticMesh->color()->y(),
staticMesh->color()->z(),
staticMesh->color()->w());
room->mesh[number].pos.Orientation = Vector3Shrt(short(staticMesh->rotation()->x()),
short(staticMesh->rotation()->y()),
short(staticMesh->rotation()->z()));
room->mesh[i].flags = staticMesh->flags();
room->mesh[i].HitPoints = staticMesh->hit_points();
room->mesh[number].color = Vector4(staticMesh->color()->x(),
staticMesh->color()->y(),
staticMesh->color()->z(),
staticMesh->color()->w());
room->mesh[number].flags = staticMesh->flags();
room->mesh[number].HitPoints = staticMesh->hit_points();
if (!room->mesh[i].flags)
if (!room->mesh[number].flags)
{
short roomNumber = staticMesh->room_number();
FloorInfo* floor = GetFloor(room->mesh[i].pos.Position.x, room->mesh[i].pos.Position.y, room->mesh[i].pos.Position.z, &roomNumber);
TestTriggers(room->mesh[i].pos.Position.x, room->mesh[i].pos.Position.y, room->mesh[i].pos.Position.z, staticMesh->room_number(), true, 0);
FloorInfo* floor = GetFloor(room->mesh[number].pos.Position.x, room->mesh[number].pos.Position.y, room->mesh[number].pos.Position.z, &roomNumber);
TestTriggers(room->mesh[number].pos.Position.x, room->mesh[number].pos.Position.y, room->mesh[number].pos.Position.z, staticMesh->room_number(), true, 0);
floor->Stopper = false;
}
}
// Volumes
for (int i = 0; i < s->volume_states()->size(); i++)
{
auto volume = s->volume_states()->Get(i);
auto room = &g_Level.Rooms[volume->room_number()];
int number = volume->number();
room->triggerVolumes[number].Position = Vector3(volume->position()->x(),
volume->position()->y(),
volume->position()->z());
room->triggerVolumes[number].Rotation = Vector4(volume->rotation()->x(),
volume->rotation()->y(),
volume->rotation()->z(),
volume->rotation()->w());
room->triggerVolumes[number].Scale = Vector3(volume->scale()->x(),
volume->scale()->y(),
volume->scale()->z());
int triggerer = volume->triggerer();
if (triggerer >= 0)
room->triggerVolumes[number].Triggerer = short(triggerer);
else
room->triggerVolumes[number].Triggerer = nullptr;
room->triggerVolumes[number].Status = TriggerStatus(volume->state());
room->triggerVolumes[number].Timeout = volume->timeout();
}
// Cameras
for (int i = 0; i < s->fixed_cameras()->size(); i++)
{
@ -1650,7 +1747,19 @@ bool SaveGame::Load(int slot)
fx.flag2 = fx_saved->flag2();
}
JustLoaded = 1;
if (g_Level.EventSets.size() == s->call_counters()->size())
{
for (int i = 0; i < s->call_counters()->size(); ++i)
{
auto cc_saved = s->call_counters()->Get(i);
g_Level.EventSets[i].OnEnter.CallCounter = cc_saved->on_enter();
g_Level.EventSets[i].OnInside.CallCounter = cc_saved->on_inside();
g_Level.EventSets[i].OnLeave.CallCounter = cc_saved->on_leave();
}
}
JustLoaded = true;
// Lara
ZeroMemory(Lara.Inventory.Puzzles, NUM_PUZZLES * sizeof(int));

View file

@ -17,9 +17,9 @@ using namespace TEN::Control::Volumes;
constexpr auto MAX_CAMERA = 18;
int TrackCameraInit;
bool TrackCameraInit;
int SpotcamTimer;
int SpotcamPaused;
bool SpotcamPaused;
int SpotcamLoopCnt;
int CameraFade;
Vector3Int LaraFixedPosition;
@ -41,7 +41,6 @@ int CameraZtarget[MAX_CAMERA];
int CameraRoll[MAX_CAMERA];
int CameraFOV[MAX_CAMERA];
int CameraSpeed[MAX_CAMERA];
QUAKE_CAMERA QuakeCam;
int SplineFromCamera;
bool SpotCamFirstLook;
short CurrentSplineCamera;
@ -50,13 +49,14 @@ int LaraHealth;
int LaraAir;
int CurrentSpotcamSequence;
SPOTCAM SpotCam[MAX_SPOTCAMS];
byte SpotCamRemap[MAX_SPOTCAMS];
byte CameraCnt[MAX_SPOTCAMS];
int SpotCamRemap[MAX_SPOTCAMS];
int CameraCnt[MAX_SPOTCAMS];
int NumberSpotcams;
int CheckTrigger = 0;
int UseSpotCam = 0;
int SpotcamDontDrawLara;
int SpotcamOverlay;
bool CheckTrigger = false;
bool UseSpotCam = false;
bool SpotcamDontDrawLara = false;
bool SpotcamOverlay = false;
void ClearSpotCamSequences()
{
@ -206,7 +206,6 @@ void InitialiseSpotCam(short Sequence)
}
}
//loc_379F8
CameraXposition[CurrentCameraCnt + 2] = SpotCam[LastCamera].x;
CameraYposition[CurrentCameraCnt + 2] = SpotCam[LastCamera].y;
CameraZposition[CurrentCameraCnt + 2] = SpotCam[LastCamera].z;
@ -219,7 +218,6 @@ void InitialiseSpotCam(short Sequence)
}
else
{
//loc_37AA8
int sp = 0;
if ((spotcam->flags & SCF_CUT_PAN))
{
@ -241,7 +239,6 @@ void InitialiseSpotCam(short Sequence)
if (LastCamera < CurrentSplineCamera)
cn = FirstCamera;
//loc_37B74
CameraXposition[sp + 2] = SpotCam[cn].x;
CameraYposition[sp + 2] = SpotCam[cn].y;
CameraZposition[sp + 2] = SpotCam[cn].z;
@ -265,12 +262,6 @@ void InitialiseSpotCam(short Sequence)
if (spotcam->flags & SCF_HIDE_LARA)
SpotcamDontDrawLara = true;
else
{
QuakeCam.spos.boxNumber = 0;
return;
}
}
else
{
@ -329,8 +320,6 @@ void InitialiseSpotCam(short Sequence)
if (spotcam->flags & SCF_HIDE_LARA)
SpotcamDontDrawLara = true;
QuakeCam.spos.boxNumber = 0;
}
void CalculateSpotCameras()
@ -392,12 +381,14 @@ void CalculateSpotCameras()
if ((SpotCam[CurrentSplineCamera].flags & SCF_SCREEN_FADE_IN) &&
CameraFade != CurrentSplineCamera)
{
SetScreenFadeIn(FADE_SCREEN_SPEED);
CameraFade = CurrentSplineCamera;
}
if ((SpotCam[CurrentSplineCamera].flags & SCF_SCREEN_FADE_OUT) &&
CameraFade != CurrentSplineCamera)
{
SetScreenFadeOut(FADE_SCREEN_SPEED);
CameraFade = CurrentSplineCamera;
}
@ -464,11 +455,12 @@ void CalculateSpotCameras()
else if (!SpotcamTimer)
CurrentSplinePosition += cspeed;
if (!(TrInput & IN_LOOK))
bool lookPressed = (TrInput & IN_LOOK) != 0;
if (!lookPressed)
SpotCamFirstLook = false;
if (s->flags & SCF_DISABLE_BREAKOUT ||
!(TrInput & IN_LOOK))
if ((s->flags & SCF_DISABLE_BREAKOUT) || !lookPressed)
{
Camera.pos.x = cpx;
Camera.pos.y = cpy;
@ -498,28 +490,17 @@ void CalculateSpotCameras()
AlterFOV(cfov);
// WTF?
if (QuakeCam.spos.boxNumber != 0)
{
dx = (Camera.pos.x - QuakeCam.epos.x);
dy = (Camera.pos.y - QuakeCam.epos.y);
dz = (Camera.pos.z - QuakeCam.epos.z);
if (sqrt(SQUARE(dx) * SQUARE(dy) * SQUARE(dz)) < QuakeCam.epos.boxNumber)
{
dz = QuakeCam.spos.roomNumber + (((QuakeCam.epos.roomNumber - QuakeCam.spos.roomNumber) * -QuakeCam.epos.boxNumber) / QuakeCam.epos.boxNumber) >> 1;
dy = QuakeCam.spos.roomNumber + (((QuakeCam.epos.roomNumber - QuakeCam.spos.roomNumber) * -QuakeCam.epos.boxNumber) / QuakeCam.epos.boxNumber);
if (dy > 0)
{
Camera.pos.x += (GetRandomControl() / dy) - dz;
Camera.pos.y += (GetRandomControl() / dy) - dz;
Camera.pos.z += (GetRandomControl() / dy) - dz;
}
}
}
LookAt(&Camera, croll);
if (SpotCam[CurrentSplineCamera].flags & SCF_OVERLAY)
SpotcamOverlay = true;
if (SpotCam[CurrentSplineCamera].flags & SCF_HIDE_LARA)
SpotcamDontDrawLara = true;
if (SpotCam[CurrentSplineCamera].flags & SCF_ACTIVATE_HEAVY_TRIGGERS)
CheckTrigger = true;
if (CheckTrigger)
{
CameraType oldType = Camera.type;
@ -541,7 +522,9 @@ void CalculateSpotCameras()
}
if (s->flags & SCF_TRACKING_CAM)
{
TrackCameraInit = true;
}
else if (CurrentSplinePosition > 0x10000 - cspeed)
{
if (SpotCam[CurrentSplineCamera].timer > 0 &&
@ -550,49 +533,7 @@ void CalculateSpotCameras()
if (!SpotcamTimer && !SpotcamPaused)
SpotcamTimer = SpotCam[CurrentSplineCamera].timer >> 3;
}
else if (SpotCam[CurrentSplineCamera].timer < 0)
SpotcamOverlay = 1; // Negative timer = sniper mode?
if (SpotCam[CurrentSplineCamera].flags & SCF_HIDE_LARA)
SpotcamDontDrawLara = true;
if (SpotCam[CurrentSplineCamera].flags & SCF_ACTIVATE_HEAVY_TRIGGERS)
CheckTrigger = true;
/* // Weird code which possibly did some shaking over the course of camera
if (SpotCam[CurrentSplineCamera].flags & SCF_STOP_MOVEMENT)
{
if (QuakeCam.spos.boxNumber == 0 || SpotCam[CurrentSplineCamera].timer != -1)
{
QuakeCam.spos.x = SpotCam[CurrentSplineCamera].x;
QuakeCam.spos.y = SpotCam[CurrentSplineCamera].y;
QuakeCam.spos.z = SpotCam[CurrentSplineCamera].z;
if (SpotCam[CurrentSplineCamera].timer != -1)
{
QuakeCam.spos.roomNumber = SpotCam[CurrentSplineCamera].timer << 3;
}
else
{
QuakeCam.spos.roomNumber = 0;
}
QuakeCam.spos.boxNumber = 1;
QuakeCam.epos.x = SpotCam[CurrentSplineCamera + 1].x;
QuakeCam.epos.y = SpotCam[CurrentSplineCamera + 1].y;
QuakeCam.epos.z = SpotCam[CurrentSplineCamera + 1].z;
if (SpotCam[CurrentSplineCamera + 1].timer != -1)
QuakeCam.epos.roomNumber = SpotCam[CurrentSplineCamera + 1].timer << 3;
else
QuakeCam.epos.roomNumber = 0;
QuakeCam.epos.boxNumber = sqrt(((QuakeCam.spos.x - QuakeCam.epos.x) * (QuakeCam.spos.x - QuakeCam.epos.x)) + ((QuakeCam.spos.y - QuakeCam.epos.y) * (QuakeCam.spos.y - QuakeCam.epos.y) + ((QuakeCam.spos.z - QuakeCam.epos.z) * (QuakeCam.spos.z - QuakeCam.epos.z))));
}
else
QuakeCam.spos.boxNumber = 0;
}
*/
if (!SpotcamTimer)
{
CurrentSplinePosition = 0;
@ -625,7 +566,7 @@ void CalculateSpotCameras()
int sp2 = 0;
if (SpotCam[CurrentSplineCamera].flags & SCF_CUT_TO_CAM)
{
cn = (SpotCam[CurrentSplineCamera].timer & 0xF) + FirstCamera;
cn = FirstCamera + SpotCam[CurrentSplineCamera].timer;
CameraXposition[1] = SpotCam[cn].x;
CameraYposition[1] = SpotCam[cn].y;
@ -718,9 +659,9 @@ void CalculateSpotCameras()
SetCinematicBars(0.0f, SPOTCAM_CINEMATIC_BARS_SPEED);
UseSpotCam = 0;
UseSpotCam = false;
Lara.Control.Locked = false;
CheckTrigger = 0;
CheckTrigger = false;
Camera.oldType = CameraType::Fixed;
Camera.type = CameraType::Chase;
Camera.speed = 1;
@ -835,6 +776,7 @@ void CalculateSpotCameras()
}
else
{
SetScreenFadeIn(FADE_SCREEN_SPEED);
SetCinematicBars(0.0f, SPOTCAM_CINEMATIC_BARS_SPEED);
UseSpotCam = false;
Lara.Control.Locked = false;

View file

@ -6,12 +6,6 @@ constexpr auto MAX_SPOTCAMS = 256;
constexpr auto SPOTCAM_CINEMATIC_BARS_HEIGHT = 1.0f / 16.0f;
constexpr auto SPOTCAM_CINEMATIC_BARS_SPEED = 1.0f / FPS;
struct QUAKE_CAMERA
{
GameVector spos;
GameVector epos;
};
struct SPOTCAM
{
int x;
@ -34,7 +28,7 @@ struct SPOTCAM
enum SPOTCAM_FLAGS
{
SCF_CUT_PAN = (1 << 0), // 0x0001 cut without panning smoothly
SCF_UNUSED = (1 << 1), // 0x0002
SCF_OVERLAY = (1 << 1), // 0x0002 TODO: add vignette
SCF_LOOP_SEQUENCE = (1 << 2), // 0x0004
SCF_TRACKING_CAM = (1 << 3), // 0x0008
SCF_HIDE_LARA = (1 << 4), // 0x0010
@ -52,14 +46,14 @@ enum SPOTCAM_FLAGS
};
extern SPOTCAM SpotCam[MAX_SPOTCAMS];
extern byte SpotCamRemap[MAX_SPOTCAMS];
extern byte CameraCnt[MAX_SPOTCAMS];
extern int SpotCamRemap[MAX_SPOTCAMS];
extern int CameraCnt[MAX_SPOTCAMS];
extern int LastSpotCamSequence;
extern int NumberSpotcams;
extern int UseSpotCam;
extern int SpotcamDontDrawLara;
extern int SpotcamOverlay;
extern int TrackCameraInit;
extern bool UseSpotCam;
extern bool SpotcamDontDrawLara;
extern bool SpotcamOverlay;
extern bool TrackCameraInit;
void ClearSpotCamSequences();
void InitSpotCamSequences();

View file

@ -13,10 +13,10 @@
#include "Game/items.h"
#include "Game/Lara/lara.h"
#include "Sound/sound.h"
#include "Specific/Input/Input.h"
#include "Specific/level.h"
#include "Specific/setup.h"
#include "Specific/trmath.h"
#include "input.h"
using namespace TEN::Input;
using namespace TEN::Effects::Lara;

View file

@ -69,7 +69,7 @@ namespace TEN::Entities::TR3
Lara.Control.HandStatus = HandStatus::Busy;
Lara.Control.Weapon.GunType = LaraWeaponType::None;
Camera.flags = 1;
Camera.flags = CF_FOLLOW_CENTER;
Camera.targetAngle = ANGLE(170.0f);
Camera.targetElevation = -ANGLE(25.0f);
}

View file

@ -683,7 +683,7 @@ namespace TEN::Entities::Vehicles
}
}
if (minecart->Velocity >= MINECART_VELOCITY_MIN)
if (minecart->Velocity > 0)
{
if (TrInput & MINECART_IN_DUCK)
laraItem->Animation.TargetState = MINECART_STATE_DUCK;

View file

@ -92,7 +92,7 @@ void RaisingCogControl(short itemNumber)
if (!item->ItemFlags[2])
{
InitialiseSpotCam(item->ItemFlags[2]);
UseSpotCam = 1;
UseSpotCam = true;
}
int flags = 0;

View file

@ -404,7 +404,7 @@ namespace TEN::Renderer
1.0f,
{ 32,
Vector3::Distance(pos1, pos2) },
BLENDMODE_OPAQUE,
BLENDMODE_ALPHABLEND,
d, view);
}
}

View file

@ -321,12 +321,13 @@ void TEN::Renderer::Renderer11::InitialiseScreen(int w, int h, bool windowed, HW
void TEN::Renderer::Renderer11::Create()
{
TENLog("Creating DX11 renderer device...", LogLevel::Info);
D3D_FEATURE_LEVEL levels[] = { D3D_FEATURE_LEVEL_10_1 };
D3D_FEATURE_LEVEL featureLevel;
HRESULT res;
#ifdef _RELEASE
#ifndef _DEBUG
res = D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, NULL, levels, 1, D3D11_SDK_VERSION, &m_device, &featureLevel, &m_context);
#else
res = D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, D3D11_CREATE_DEVICE_DEBUG, levels, 1, D3D11_SDK_VERSION, &m_device, &featureLevel, &m_context); // D3D11_CREATE_DEVICE_DEBUG

View file

@ -247,7 +247,7 @@ void Renderer11::UpdateLaraAnimations(bool force)
void TEN::Renderer::Renderer11::DrawLara(RenderView& view, bool transparent)
{
// Don't draw Lara if binoculars or sniper
if (BinocularRange || SpotcamOverlay || SpotcamDontDrawLara || CurrentLevel == 0)
if (BinocularRange || SpotcamDontDrawLara || CurrentLevel == 0)
return;
RendererItem* item = &m_items[Lara.ItemNumber];

View file

@ -48,7 +48,7 @@ BEGIN
VALUE "LegalCopyright", "Copyright (C) 2022"
VALUE "OriginalFilename", "TombEngine.exe"
VALUE "ProductName", "Tomb Engine"
VALUE "ProductVersion", "1.0.0.0"
VALUE "ProductVersion", "1.5.1.0"
END
END
BLOCK "VarFileInfo"

View file

@ -36,8 +36,8 @@ public:
virtual void FreeLevelScripts() = 0;
virtual void ResetScripts(bool clearGameVars) = 0;
virtual void ExecuteScriptFile(std::string const& luaFileName) = 0;
virtual void ExecuteFunction(std::string const& luaFuncName, TEN::Control::Volumes::VolumeTriggerer) = 0;
virtual void ExecuteFunction(std::string const& luaFuncName, short idOne, short idTwo) = 0;
virtual void ExecuteFunction(std::string const& luaFuncName, TEN::Control::Volumes::VolumeTriggerer, std::string const& arguments) = 0;
virtual void ExecuteFunction(std::string const& luaFuncName, short idOne, short idTwo = 0) = 0;
virtual void GetVariables(std::vector<SavedVar> & vars) = 0;
virtual void SetVariables(std::vector<SavedVar> const& vars) = 0;

View file

@ -145,8 +145,8 @@ static constexpr char ScriptReserved_SetCineBars[] = "SetCineBars";
static constexpr char ScriptReserved_SetFOV[] = "SetFOV";
static constexpr char ScriptReserved_GetFOV[] = "GetFOV";
static constexpr char ScriptReserved_KeyHeld[] = "KeyHeld";
static constexpr char ScriptReserved_KeyHit[] = "KeyHit";
static constexpr char ScriptReserved_KeyIsHeld[] = "KeyIsHeld";
static constexpr char ScriptReserved_KeyIsHit[] = "KeyIsHit";
static constexpr char ScriptReserved_KeyPush[] = "KeyPush";
static constexpr char ScriptReserved_KeyClear[] = "KeyClear";

View file

@ -369,29 +369,29 @@ void LogicHandler::ExecuteScriptFile(const std::string & luaFilename)
m_handler.ExecuteScript(luaFilename);
}
void LogicHandler::ExecuteFunction(std::string const& luaFuncName, short idOne, short idTwo)
void LogicHandler::ExecuteFunction(std::string const& name, short idOne, short idTwo)
{
sol::protected_function_result r;
sol::protected_function func = (*m_handler.GetState())["LevelFuncs"][luaFuncName.c_str()];
sol::protected_function func = (*m_handler.GetState())["LevelFuncs"][name.c_str()];
r = func(std::make_unique<Moveable>(idOne), std::make_unique<Moveable>(idTwo));
if (!r.valid())
{
sol::error err = r;
ScriptAssertF(false, "Could not execute function {}: {}", luaFuncName, err.what());
ScriptAssertF(false, "Could not execute function {}: {}", name, err.what());
}
}
void LogicHandler::ExecuteFunction(std::string const& name, TEN::Control::Volumes::VolumeTriggerer triggerer)
void LogicHandler::ExecuteFunction(std::string const& name, TEN::Control::Volumes::VolumeTriggerer triggerer, std::string const& arguments)
{
sol::protected_function_result r;
sol::protected_function func = (*m_handler.GetState())["LevelFuncs"][name.c_str()];
if (std::holds_alternative<short>(triggerer))
{
r = func(std::make_unique<Moveable>(std::get<short>(triggerer), true));
r = func(std::make_unique<Moveable>(std::get<short>(triggerer), true), arguments);
}
else
{
r = func();
r = func(nullptr, arguments);
}
if (!r.valid())
@ -401,7 +401,8 @@ void LogicHandler::ExecuteFunction(std::string const& name, TEN::Control::Volume
}
}
static void doCallback(sol::protected_function const & func, std::optional<float> dt = std::nullopt) {
static void doCallback(sol::protected_function const & func, std::optional<float> dt = std::nullopt)
{
auto r = dt.has_value() ? func(dt) : func();
if (!r.valid())

View file

@ -54,9 +54,9 @@ public:
sol::protected_function GetLevelFunc(sol::table tab, std::string const& luaName);
void ExecuteScriptFile(const std::string& luaFilename) override;
void ExecuteFunction(std::string const & name, TEN::Control::Volumes::VolumeTriggerer) override;
void ExecuteFunction(std::string const& name, TEN::Control::Volumes::VolumeTriggerer, std::string const& arguments) override;
void ExecuteFunction(std::string const& luaFuncName, short idOne, short idTwo) override;
void ExecuteFunction(std::string const& name, short idOne, short idTwo) override;
void GetVariables(std::vector<SavedVar>& vars) override;
void ResetVariables();

View file

@ -10,7 +10,7 @@
#include "Game/effects/weather.h"
#include "Sound/sound.h"
#include "Specific/configuration.h"
#include "Specific/input.h"
#include "Specific/Input/Input.h"
/***
Functions that don't fit in the other modules.
@ -125,12 +125,12 @@ namespace Misc
SoundEffect(id, p.has_value() ? &PHD_3DPOS(p.value().x, p.value().y, p.value().z) : nullptr, SoundEnvironment::Always);
}
static bool KeyHeld(int actionIndex)
static bool KeyIsHeld(int actionIndex)
{
return (TrInput & (1 << actionIndex)) != 0;
}
static bool KeyHit(int actionIndex)
static bool KeyIsHit(int actionIndex)
{
return (DbInput & (1 << actionIndex)) != 0;
}
@ -229,14 +229,14 @@ namespace Misc
table_misc.set_function(ScriptReserved_PlaySound, &PlaySoundEffect);
/// Check if particular action key is held
//@function KeyHeld
//@function KeyIsHeld
//@tparam int action mapping index to check
table_misc.set_function(ScriptReserved_KeyHeld, &KeyHeld);
table_misc.set_function(ScriptReserved_KeyIsHeld, &KeyIsHeld);
/// Check if particular action key was hit (once)
//@function KeyHit
//@function KeyIsHit
//@tparam int action mapping index to check
table_misc.set_function(ScriptReserved_KeyHit, &KeyHit);
table_misc.set_function(ScriptReserved_KeyIsHit, &KeyIsHit);
/// Emulate pushing of a certain action key
//@function KeyPush

View file

@ -336,8 +336,6 @@ void LoadObjects()
Objects[objNum].frameBase = ReadInt32();
Objects[objNum].animIndex = ReadInt32();
ReadInt16();
Objects[objNum].loaded = true;
}
@ -417,11 +415,7 @@ void LoadCameras()
sink.z = ReadInt32();
sink.strength = ReadInt32();
sink.boxIndex = ReadInt32();
byte numBytes = ReadInt8();
char buffer[255];
ReadBytes(buffer, numBytes);
sink.luaName = std::string(buffer, buffer+numBytes);
sink.luaName = ReadString();
g_GameScriptEntities->AddName(sink.luaName, sink);
}
@ -778,24 +772,9 @@ void ReadRooms()
volume.Scale.y = ReadFloat();
volume.Scale.z = ReadFloat();
volume.Activators = ReadInt32();
volume.EventSetIndex = ReadInt32();
byte numBytes = ReadInt8();
char buffer[255];
ReadBytes(buffer, numBytes);
volume.OnEnter = std::string(buffer, buffer+numBytes);
numBytes = ReadInt8();
ReadBytes(buffer, numBytes);
volume.OnInside = std::string(buffer, buffer+numBytes);
numBytes = ReadInt8();
ReadBytes(buffer, numBytes);
volume.OnLeave = std::string(buffer, buffer+numBytes);
volume.OneShot = ReadInt8();
volume.Status = TriggerStatus::Outside;
volume.Box = BoundingOrientedBox(volume.Position, volume.Scale, volume.Rotation);
volume.Sphere = BoundingSphere(volume.Position, volume.Scale.x);
@ -861,7 +840,7 @@ void FreeLevel()
g_Level.Sinks.resize(0);
g_Level.SoundSources.resize(0);
g_Level.AIObjects.resize(0);
g_Level.LuaFunctionNames.resize(0);
g_Level.EventSets.resize(0);
g_Level.Items.resize(0);
for (int i = 0; i < 2; i++)
@ -900,11 +879,7 @@ void LoadSoundSources()
source.z = ReadInt32();
source.soundId = ReadInt32();
source.flags = ReadInt32();
byte numBytes = ReadInt8();
char buffer[255];
ReadBytes(buffer, numBytes);
source.luaName = std::string(buffer, buffer+numBytes);
source.luaName = ReadString();
g_GameScriptEntities->AddName(source.luaName, source);
}
@ -938,34 +913,6 @@ void LoadAnimatedTextures()
g_Level.AnimatedTexturesSequences.push_back(sequence);
}
// Unused for now
int nAnimUVRanges = ReadInt8();
}
void LoadTextureInfos()
{
// TODO: THIS FUNCTION IS DUMMY!!!! REMOVE IT WHEN TE FORMAT IS CHANGED! -- Lwmte 31.07.22
ReadInt32(); // TEX/0
int numObjectTextures = ReadInt32();
TENLog("Num texinfos: " + std::to_string(numObjectTextures), LogLevel::Info);
for (int i = 0; i < numObjectTextures; i++)
{
ReadInt32();
ReadInt32();
ReadInt32();
for (int j = 0; j < 4; j++)
{
ReadFloat();
ReadFloat();
}
ReadInt32();
}
}
void LoadAIObjects()
@ -987,23 +934,41 @@ void LoadAIObjects()
obj.flags = ReadInt16();
obj.yRot = ReadInt16();
obj.boxNumber = ReadInt32();
byte numBytes = ReadInt8();
char buffer[255];
ReadBytes(buffer, numBytes);
obj.luaName = std::string(buffer, buffer+numBytes);
obj.luaName = ReadString();
g_GameScriptEntities->AddName(obj.luaName, obj);
}
}
void LoadLuaFunctionNames()
void LoadEventSets()
{
TENLog("Parsing Lua function names... ", LogLevel::Info);
int eventSetCount = ReadInt32();
TENLog("Num level sets: " + std::to_string(eventSetCount), LogLevel::Info);
int luaFunctionsCount = ReadInt32();
for (int i = 0; i < luaFunctionsCount; i++)
g_Level.LuaFunctionNames.push_back(ReadString());
for (int i = 0; i < eventSetCount; i++)
{
auto eventSet = VolumeEventSet();
eventSet.Name = ReadString();
eventSet.Activators = ReadInt32();
eventSet.OnEnter.Mode = (VolumeEventMode)ReadInt32();
eventSet.OnEnter.Function = ReadString();
eventSet.OnEnter.Argument = ReadString();
eventSet.OnEnter.CallCounter = ReadInt32();
eventSet.OnInside.Mode = (VolumeEventMode)ReadInt32();
eventSet.OnInside.Function = ReadString();
eventSet.OnInside.Argument = ReadString();
eventSet.OnInside.CallCounter = ReadInt32();
eventSet.OnLeave.Mode = (VolumeEventMode)ReadInt32();
eventSet.OnLeave.Function = ReadString();
eventSet.OnLeave.Argument = ReadString();
eventSet.OnLeave.CallCounter = ReadInt32();
g_Level.EventSets.push_back(eventSet);
}
}
FILE* FileOpen(const char* fileName)
@ -1145,13 +1110,12 @@ unsigned int _stdcall LoadLevel(void* data)
//InitialiseLOTarray(true);
LoadAnimatedTextures();
LoadTextureInfos();
g_Renderer.UpdateProgress(70);
LoadItems();
LoadAIObjects();
LoadLuaFunctionNames();
LoadEventSets();
LoadSamples();
g_Renderer.UpdateProgress(80);

View file

@ -1,5 +1,6 @@
#pragma once
#include "Game/animation.h"
#include "Game/control/volumetriggerer.h"
#include "Game/items.h"
#include "Game/room.h"
#include "Specific/IO/ChunkId.h"
@ -13,18 +14,14 @@
#define MAX_ZONES 6
using namespace TEN::Control::Volumes;
struct ChunkId;
struct LEB128;
struct SampleInfo;
struct BOX_INFO;
struct OVERLAP;
struct OBJECT_TEXTURE_VERT
{
float x;
float y;
};
struct TEXTURE
{
int width;
@ -121,7 +118,7 @@ struct LEVEL
std::vector<short> SoundMap;
std::vector<SampleInfo> SoundDetails;
std::vector<ANIMATED_TEXTURES_SEQUENCE> AnimatedTexturesSequences;
std::vector<std::string> LuaFunctionNames;
std::vector<VolumeEventSet> EventSets;
int NumItems;
int NumSpritesSequences;
};
@ -149,7 +146,6 @@ void LoadBoxes();
void LoadSamples();
void LoadSoundSources();
void LoadAnimatedTextures();
void LoadTextureInfos();
void LoadAIObjects();
void InitialiseLara(int restore);

View file

@ -125,6 +125,14 @@ struct Pendulum;
struct PendulumBuilder;
struct PendulumT;
struct EventSetCallCounters;
struct EventSetCallCountersBuilder;
struct EventSetCallCountersT;
struct VolumeState;
struct VolumeStateBuilder;
struct VolumeStateT;
struct KeyValPair;
struct ScriptTable;
@ -4021,9 +4029,12 @@ flatbuffers::Offset<Sink> CreateSink(flatbuffers::FlatBufferBuilder &_fbb, const
struct StaticMeshInfoT : public flatbuffers::NativeTable {
typedef StaticMeshInfo TableType;
int32_t number = 0;
int32_t room_number = 0;
std::unique_ptr<TEN::Save::Vector3> position{};
std::unique_ptr<TEN::Save::Vector3> rotation{};
std::unique_ptr<TEN::Save::Vector4> color{};
int32_t hit_points = 0;
int32_t room_number = 0;
int32_t flags = 0;
};
@ -4032,28 +4043,43 @@ struct StaticMeshInfo FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
typedef StaticMeshInfoBuilder Builder;
struct Traits;
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_COLOR = 4,
VT_HIT_POINTS = 6,
VT_ROOM_NUMBER = 8,
VT_FLAGS = 10
VT_NUMBER = 4,
VT_ROOM_NUMBER = 6,
VT_POSITION = 8,
VT_ROTATION = 10,
VT_COLOR = 12,
VT_HIT_POINTS = 14,
VT_FLAGS = 16
};
int32_t number() const {
return GetField<int32_t>(VT_NUMBER, 0);
}
int32_t room_number() const {
return GetField<int32_t>(VT_ROOM_NUMBER, 0);
}
const TEN::Save::Vector3 *position() const {
return GetStruct<const TEN::Save::Vector3 *>(VT_POSITION);
}
const TEN::Save::Vector3 *rotation() const {
return GetStruct<const TEN::Save::Vector3 *>(VT_ROTATION);
}
const TEN::Save::Vector4 *color() const {
return GetStruct<const TEN::Save::Vector4 *>(VT_COLOR);
}
int32_t hit_points() const {
return GetField<int32_t>(VT_HIT_POINTS, 0);
}
int32_t room_number() const {
return GetField<int32_t>(VT_ROOM_NUMBER, 0);
}
int32_t flags() const {
return GetField<int32_t>(VT_FLAGS, 0);
}
bool Verify(flatbuffers::Verifier &verifier) const {
return VerifyTableStart(verifier) &&
VerifyField<int32_t>(verifier, VT_NUMBER) &&
VerifyField<int32_t>(verifier, VT_ROOM_NUMBER) &&
VerifyField<TEN::Save::Vector3>(verifier, VT_POSITION) &&
VerifyField<TEN::Save::Vector3>(verifier, VT_ROTATION) &&
VerifyField<TEN::Save::Vector4>(verifier, VT_COLOR) &&
VerifyField<int32_t>(verifier, VT_HIT_POINTS) &&
VerifyField<int32_t>(verifier, VT_ROOM_NUMBER) &&
VerifyField<int32_t>(verifier, VT_FLAGS) &&
verifier.EndTable();
}
@ -4066,15 +4092,24 @@ struct StaticMeshInfoBuilder {
typedef StaticMeshInfo Table;
flatbuffers::FlatBufferBuilder &fbb_;
flatbuffers::uoffset_t start_;
void add_number(int32_t number) {
fbb_.AddElement<int32_t>(StaticMeshInfo::VT_NUMBER, number, 0);
}
void add_room_number(int32_t room_number) {
fbb_.AddElement<int32_t>(StaticMeshInfo::VT_ROOM_NUMBER, room_number, 0);
}
void add_position(const TEN::Save::Vector3 *position) {
fbb_.AddStruct(StaticMeshInfo::VT_POSITION, position);
}
void add_rotation(const TEN::Save::Vector3 *rotation) {
fbb_.AddStruct(StaticMeshInfo::VT_ROTATION, rotation);
}
void add_color(const TEN::Save::Vector4 *color) {
fbb_.AddStruct(StaticMeshInfo::VT_COLOR, color);
}
void add_hit_points(int32_t hit_points) {
fbb_.AddElement<int32_t>(StaticMeshInfo::VT_HIT_POINTS, hit_points, 0);
}
void add_room_number(int32_t room_number) {
fbb_.AddElement<int32_t>(StaticMeshInfo::VT_ROOM_NUMBER, room_number, 0);
}
void add_flags(int32_t flags) {
fbb_.AddElement<int32_t>(StaticMeshInfo::VT_FLAGS, flags, 0);
}
@ -4091,15 +4126,21 @@ struct StaticMeshInfoBuilder {
inline flatbuffers::Offset<StaticMeshInfo> CreateStaticMeshInfo(
flatbuffers::FlatBufferBuilder &_fbb,
int32_t number = 0,
int32_t room_number = 0,
const TEN::Save::Vector3 *position = 0,
const TEN::Save::Vector3 *rotation = 0,
const TEN::Save::Vector4 *color = 0,
int32_t hit_points = 0,
int32_t room_number = 0,
int32_t flags = 0) {
StaticMeshInfoBuilder builder_(_fbb);
builder_.add_flags(flags);
builder_.add_room_number(room_number);
builder_.add_hit_points(hit_points);
builder_.add_color(color);
builder_.add_rotation(rotation);
builder_.add_position(position);
builder_.add_room_number(room_number);
builder_.add_number(number);
return builder_.Finish();
}
@ -5408,6 +5449,221 @@ struct Pendulum::Traits {
flatbuffers::Offset<Pendulum> CreatePendulum(flatbuffers::FlatBufferBuilder &_fbb, const PendulumT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
struct EventSetCallCountersT : public flatbuffers::NativeTable {
typedef EventSetCallCounters TableType;
int32_t on_enter = 0;
int32_t on_inside = 0;
int32_t on_leave = 0;
};
struct EventSetCallCounters FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
typedef EventSetCallCountersT NativeTableType;
typedef EventSetCallCountersBuilder Builder;
struct Traits;
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_ON_ENTER = 4,
VT_ON_INSIDE = 6,
VT_ON_LEAVE = 8
};
int32_t on_enter() const {
return GetField<int32_t>(VT_ON_ENTER, 0);
}
int32_t on_inside() const {
return GetField<int32_t>(VT_ON_INSIDE, 0);
}
int32_t on_leave() const {
return GetField<int32_t>(VT_ON_LEAVE, 0);
}
bool Verify(flatbuffers::Verifier &verifier) const {
return VerifyTableStart(verifier) &&
VerifyField<int32_t>(verifier, VT_ON_ENTER) &&
VerifyField<int32_t>(verifier, VT_ON_INSIDE) &&
VerifyField<int32_t>(verifier, VT_ON_LEAVE) &&
verifier.EndTable();
}
EventSetCallCountersT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
void UnPackTo(EventSetCallCountersT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
static flatbuffers::Offset<EventSetCallCounters> Pack(flatbuffers::FlatBufferBuilder &_fbb, const EventSetCallCountersT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
};
struct EventSetCallCountersBuilder {
typedef EventSetCallCounters Table;
flatbuffers::FlatBufferBuilder &fbb_;
flatbuffers::uoffset_t start_;
void add_on_enter(int32_t on_enter) {
fbb_.AddElement<int32_t>(EventSetCallCounters::VT_ON_ENTER, on_enter, 0);
}
void add_on_inside(int32_t on_inside) {
fbb_.AddElement<int32_t>(EventSetCallCounters::VT_ON_INSIDE, on_inside, 0);
}
void add_on_leave(int32_t on_leave) {
fbb_.AddElement<int32_t>(EventSetCallCounters::VT_ON_LEAVE, on_leave, 0);
}
explicit EventSetCallCountersBuilder(flatbuffers::FlatBufferBuilder &_fbb)
: fbb_(_fbb) {
start_ = fbb_.StartTable();
}
flatbuffers::Offset<EventSetCallCounters> Finish() {
const auto end = fbb_.EndTable(start_);
auto o = flatbuffers::Offset<EventSetCallCounters>(end);
return o;
}
};
inline flatbuffers::Offset<EventSetCallCounters> CreateEventSetCallCounters(
flatbuffers::FlatBufferBuilder &_fbb,
int32_t on_enter = 0,
int32_t on_inside = 0,
int32_t on_leave = 0) {
EventSetCallCountersBuilder builder_(_fbb);
builder_.add_on_leave(on_leave);
builder_.add_on_inside(on_inside);
builder_.add_on_enter(on_enter);
return builder_.Finish();
}
struct EventSetCallCounters::Traits {
using type = EventSetCallCounters;
static auto constexpr Create = CreateEventSetCallCounters;
};
flatbuffers::Offset<EventSetCallCounters> CreateEventSetCallCounters(flatbuffers::FlatBufferBuilder &_fbb, const EventSetCallCountersT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
struct VolumeStateT : public flatbuffers::NativeTable {
typedef VolumeState TableType;
int32_t number = 0;
int32_t room_number = 0;
std::unique_ptr<TEN::Save::Vector3> position{};
std::unique_ptr<TEN::Save::Vector4> rotation{};
std::unique_ptr<TEN::Save::Vector3> scale{};
int32_t state = 0;
int32_t triggerer = 0;
int32_t timeout = 0;
};
struct VolumeState FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
typedef VolumeStateT NativeTableType;
typedef VolumeStateBuilder Builder;
struct Traits;
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_NUMBER = 4,
VT_ROOM_NUMBER = 6,
VT_POSITION = 8,
VT_ROTATION = 10,
VT_SCALE = 12,
VT_STATE = 14,
VT_TRIGGERER = 16,
VT_TIMEOUT = 18
};
int32_t number() const {
return GetField<int32_t>(VT_NUMBER, 0);
}
int32_t room_number() const {
return GetField<int32_t>(VT_ROOM_NUMBER, 0);
}
const TEN::Save::Vector3 *position() const {
return GetStruct<const TEN::Save::Vector3 *>(VT_POSITION);
}
const TEN::Save::Vector4 *rotation() const {
return GetStruct<const TEN::Save::Vector4 *>(VT_ROTATION);
}
const TEN::Save::Vector3 *scale() const {
return GetStruct<const TEN::Save::Vector3 *>(VT_SCALE);
}
int32_t state() const {
return GetField<int32_t>(VT_STATE, 0);
}
int32_t triggerer() const {
return GetField<int32_t>(VT_TRIGGERER, 0);
}
int32_t timeout() const {
return GetField<int32_t>(VT_TIMEOUT, 0);
}
bool Verify(flatbuffers::Verifier &verifier) const {
return VerifyTableStart(verifier) &&
VerifyField<int32_t>(verifier, VT_NUMBER) &&
VerifyField<int32_t>(verifier, VT_ROOM_NUMBER) &&
VerifyField<TEN::Save::Vector3>(verifier, VT_POSITION) &&
VerifyField<TEN::Save::Vector4>(verifier, VT_ROTATION) &&
VerifyField<TEN::Save::Vector3>(verifier, VT_SCALE) &&
VerifyField<int32_t>(verifier, VT_STATE) &&
VerifyField<int32_t>(verifier, VT_TRIGGERER) &&
VerifyField<int32_t>(verifier, VT_TIMEOUT) &&
verifier.EndTable();
}
VolumeStateT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const;
void UnPackTo(VolumeStateT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const;
static flatbuffers::Offset<VolumeState> Pack(flatbuffers::FlatBufferBuilder &_fbb, const VolumeStateT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
};
struct VolumeStateBuilder {
typedef VolumeState Table;
flatbuffers::FlatBufferBuilder &fbb_;
flatbuffers::uoffset_t start_;
void add_number(int32_t number) {
fbb_.AddElement<int32_t>(VolumeState::VT_NUMBER, number, 0);
}
void add_room_number(int32_t room_number) {
fbb_.AddElement<int32_t>(VolumeState::VT_ROOM_NUMBER, room_number, 0);
}
void add_position(const TEN::Save::Vector3 *position) {
fbb_.AddStruct(VolumeState::VT_POSITION, position);
}
void add_rotation(const TEN::Save::Vector4 *rotation) {
fbb_.AddStruct(VolumeState::VT_ROTATION, rotation);
}
void add_scale(const TEN::Save::Vector3 *scale) {
fbb_.AddStruct(VolumeState::VT_SCALE, scale);
}
void add_state(int32_t state) {
fbb_.AddElement<int32_t>(VolumeState::VT_STATE, state, 0);
}
void add_triggerer(int32_t triggerer) {
fbb_.AddElement<int32_t>(VolumeState::VT_TRIGGERER, triggerer, 0);
}
void add_timeout(int32_t timeout) {
fbb_.AddElement<int32_t>(VolumeState::VT_TIMEOUT, timeout, 0);
}
explicit VolumeStateBuilder(flatbuffers::FlatBufferBuilder &_fbb)
: fbb_(_fbb) {
start_ = fbb_.StartTable();
}
flatbuffers::Offset<VolumeState> Finish() {
const auto end = fbb_.EndTable(start_);
auto o = flatbuffers::Offset<VolumeState>(end);
return o;
}
};
inline flatbuffers::Offset<VolumeState> CreateVolumeState(
flatbuffers::FlatBufferBuilder &_fbb,
int32_t number = 0,
int32_t room_number = 0,
const TEN::Save::Vector3 *position = 0,
const TEN::Save::Vector4 *rotation = 0,
const TEN::Save::Vector3 *scale = 0,
int32_t state = 0,
int32_t triggerer = 0,
int32_t timeout = 0) {
VolumeStateBuilder builder_(_fbb);
builder_.add_timeout(timeout);
builder_.add_triggerer(triggerer);
builder_.add_state(state);
builder_.add_scale(scale);
builder_.add_rotation(rotation);
builder_.add_position(position);
builder_.add_room_number(room_number);
builder_.add_number(number);
return builder_.Finish();
}
struct VolumeState::Traits {
using type = VolumeState;
static auto constexpr Create = CreateVolumeState;
};
flatbuffers::Offset<VolumeState> CreateVolumeState(flatbuffers::FlatBufferBuilder &_fbb, const VolumeStateT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
struct ScriptTableT : public flatbuffers::NativeTable {
typedef ScriptTable TableType;
std::vector<TEN::Save::KeyValPair> keys_vals{};
@ -6145,6 +6401,8 @@ struct SaveGameT : public flatbuffers::NativeTable {
std::unique_ptr<TEN::Save::RopeT> rope{};
std::unique_ptr<TEN::Save::PendulumT> pendulum{};
std::unique_ptr<TEN::Save::PendulumT> alternate_pendulum{};
std::vector<std::unique_ptr<TEN::Save::VolumeStateT>> volume_states{};
std::vector<std::unique_ptr<TEN::Save::EventSetCallCountersT>> call_counters{};
std::unique_ptr<TEN::Save::UnionVecT> script_vars{};
};
@ -6186,7 +6444,9 @@ struct SaveGame FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
VT_ROPE = 64,
VT_PENDULUM = 66,
VT_ALTERNATE_PENDULUM = 68,
VT_SCRIPT_VARS = 70
VT_VOLUME_STATES = 70,
VT_CALL_COUNTERS = 72,
VT_SCRIPT_VARS = 74
};
const TEN::Save::SaveGameHeader *header() const {
return GetPointer<const TEN::Save::SaveGameHeader *>(VT_HEADER);
@ -6287,6 +6547,12 @@ struct SaveGame FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
const TEN::Save::Pendulum *alternate_pendulum() const {
return GetPointer<const TEN::Save::Pendulum *>(VT_ALTERNATE_PENDULUM);
}
const flatbuffers::Vector<flatbuffers::Offset<TEN::Save::VolumeState>> *volume_states() const {
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<TEN::Save::VolumeState>> *>(VT_VOLUME_STATES);
}
const flatbuffers::Vector<flatbuffers::Offset<TEN::Save::EventSetCallCounters>> *call_counters() const {
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<TEN::Save::EventSetCallCounters>> *>(VT_CALL_COUNTERS);
}
const TEN::Save::UnionVec *script_vars() const {
return GetPointer<const TEN::Save::UnionVec *>(VT_SCRIPT_VARS);
}
@ -6360,6 +6626,12 @@ struct SaveGame FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
verifier.VerifyTable(pendulum()) &&
VerifyOffset(verifier, VT_ALTERNATE_PENDULUM) &&
verifier.VerifyTable(alternate_pendulum()) &&
VerifyOffset(verifier, VT_VOLUME_STATES) &&
verifier.VerifyVector(volume_states()) &&
verifier.VerifyVectorOfTables(volume_states()) &&
VerifyOffset(verifier, VT_CALL_COUNTERS) &&
verifier.VerifyVector(call_counters()) &&
verifier.VerifyVectorOfTables(call_counters()) &&
VerifyOffset(verifier, VT_SCRIPT_VARS) &&
verifier.VerifyTable(script_vars()) &&
verifier.EndTable();
@ -6472,6 +6744,12 @@ struct SaveGameBuilder {
void add_alternate_pendulum(flatbuffers::Offset<TEN::Save::Pendulum> alternate_pendulum) {
fbb_.AddOffset(SaveGame::VT_ALTERNATE_PENDULUM, alternate_pendulum);
}
void add_volume_states(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<TEN::Save::VolumeState>>> volume_states) {
fbb_.AddOffset(SaveGame::VT_VOLUME_STATES, volume_states);
}
void add_call_counters(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<TEN::Save::EventSetCallCounters>>> call_counters) {
fbb_.AddOffset(SaveGame::VT_CALL_COUNTERS, call_counters);
}
void add_script_vars(flatbuffers::Offset<TEN::Save::UnionVec> script_vars) {
fbb_.AddOffset(SaveGame::VT_SCRIPT_VARS, script_vars);
}
@ -6521,11 +6799,15 @@ inline flatbuffers::Offset<SaveGame> CreateSaveGame(
flatbuffers::Offset<TEN::Save::Rope> rope = 0,
flatbuffers::Offset<TEN::Save::Pendulum> pendulum = 0,
flatbuffers::Offset<TEN::Save::Pendulum> alternate_pendulum = 0,
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<TEN::Save::VolumeState>>> volume_states = 0,
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<TEN::Save::EventSetCallCounters>>> call_counters = 0,
flatbuffers::Offset<TEN::Save::UnionVec> script_vars = 0) {
SaveGameBuilder builder_(_fbb);
builder_.add_oneshot_position(oneshot_position);
builder_.add_ambient_position(ambient_position);
builder_.add_script_vars(script_vars);
builder_.add_call_counters(call_counters);
builder_.add_volume_states(volume_states);
builder_.add_alternate_pendulum(alternate_pendulum);
builder_.add_pendulum(pendulum);
builder_.add_rope(rope);
@ -6600,6 +6882,8 @@ inline flatbuffers::Offset<SaveGame> CreateSaveGameDirect(
flatbuffers::Offset<TEN::Save::Rope> rope = 0,
flatbuffers::Offset<TEN::Save::Pendulum> pendulum = 0,
flatbuffers::Offset<TEN::Save::Pendulum> alternate_pendulum = 0,
const std::vector<flatbuffers::Offset<TEN::Save::VolumeState>> *volume_states = nullptr,
const std::vector<flatbuffers::Offset<TEN::Save::EventSetCallCounters>> *call_counters = nullptr,
flatbuffers::Offset<TEN::Save::UnionVec> script_vars = 0) {
auto items__ = items ? _fbb.CreateVector<flatbuffers::Offset<TEN::Save::Item>>(*items) : 0;
auto room_items__ = room_items ? _fbb.CreateVector<int32_t>(*room_items) : 0;
@ -6618,6 +6902,8 @@ inline flatbuffers::Offset<SaveGame> CreateSaveGameDirect(
auto ambient_track__ = ambient_track ? _fbb.CreateString(ambient_track) : 0;
auto oneshot_track__ = oneshot_track ? _fbb.CreateString(oneshot_track) : 0;
auto cd_flags__ = cd_flags ? _fbb.CreateVector<int32_t>(*cd_flags) : 0;
auto volume_states__ = volume_states ? _fbb.CreateVector<flatbuffers::Offset<TEN::Save::VolumeState>>(*volume_states) : 0;
auto call_counters__ = call_counters ? _fbb.CreateVector<flatbuffers::Offset<TEN::Save::EventSetCallCounters>>(*call_counters) : 0;
return TEN::Save::CreateSaveGame(
_fbb,
header,
@ -6653,6 +6939,8 @@ inline flatbuffers::Offset<SaveGame> CreateSaveGameDirect(
rope,
pendulum,
alternate_pendulum,
volume_states__,
call_counters__,
script_vars);
}
@ -7736,9 +8024,12 @@ inline StaticMeshInfoT *StaticMeshInfo::UnPack(const flatbuffers::resolver_funct
inline void StaticMeshInfo::UnPackTo(StaticMeshInfoT *_o, const flatbuffers::resolver_function_t *_resolver) const {
(void)_o;
(void)_resolver;
{ auto _e = number(); _o->number = _e; }
{ auto _e = room_number(); _o->room_number = _e; }
{ auto _e = position(); if (_e) _o->position = std::unique_ptr<TEN::Save::Vector3>(new TEN::Save::Vector3(*_e)); }
{ auto _e = rotation(); if (_e) _o->rotation = std::unique_ptr<TEN::Save::Vector3>(new TEN::Save::Vector3(*_e)); }
{ auto _e = color(); if (_e) _o->color = std::unique_ptr<TEN::Save::Vector4>(new TEN::Save::Vector4(*_e)); }
{ auto _e = hit_points(); _o->hit_points = _e; }
{ auto _e = room_number(); _o->room_number = _e; }
{ auto _e = flags(); _o->flags = _e; }
}
@ -7750,15 +8041,21 @@ inline flatbuffers::Offset<StaticMeshInfo> CreateStaticMeshInfo(flatbuffers::Fla
(void)_rehasher;
(void)_o;
struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const StaticMeshInfoT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
auto _number = _o->number;
auto _room_number = _o->room_number;
auto _position = _o->position ? _o->position.get() : 0;
auto _rotation = _o->rotation ? _o->rotation.get() : 0;
auto _color = _o->color ? _o->color.get() : 0;
auto _hit_points = _o->hit_points;
auto _room_number = _o->room_number;
auto _flags = _o->flags;
return TEN::Save::CreateStaticMeshInfo(
_fbb,
_number,
_room_number,
_position,
_rotation,
_color,
_hit_points,
_room_number,
_flags);
}
@ -8178,6 +8475,85 @@ inline flatbuffers::Offset<Pendulum> CreatePendulum(flatbuffers::FlatBufferBuild
_node);
}
inline EventSetCallCountersT *EventSetCallCounters::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
auto _o = std::make_unique<EventSetCallCountersT>();
UnPackTo(_o.get(), _resolver);
return _o.release();
}
inline void EventSetCallCounters::UnPackTo(EventSetCallCountersT *_o, const flatbuffers::resolver_function_t *_resolver) const {
(void)_o;
(void)_resolver;
{ auto _e = on_enter(); _o->on_enter = _e; }
{ auto _e = on_inside(); _o->on_inside = _e; }
{ auto _e = on_leave(); _o->on_leave = _e; }
}
inline flatbuffers::Offset<EventSetCallCounters> EventSetCallCounters::Pack(flatbuffers::FlatBufferBuilder &_fbb, const EventSetCallCountersT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
return CreateEventSetCallCounters(_fbb, _o, _rehasher);
}
inline flatbuffers::Offset<EventSetCallCounters> CreateEventSetCallCounters(flatbuffers::FlatBufferBuilder &_fbb, const EventSetCallCountersT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
(void)_rehasher;
(void)_o;
struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const EventSetCallCountersT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
auto _on_enter = _o->on_enter;
auto _on_inside = _o->on_inside;
auto _on_leave = _o->on_leave;
return TEN::Save::CreateEventSetCallCounters(
_fbb,
_on_enter,
_on_inside,
_on_leave);
}
inline VolumeStateT *VolumeState::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
auto _o = std::make_unique<VolumeStateT>();
UnPackTo(_o.get(), _resolver);
return _o.release();
}
inline void VolumeState::UnPackTo(VolumeStateT *_o, const flatbuffers::resolver_function_t *_resolver) const {
(void)_o;
(void)_resolver;
{ auto _e = number(); _o->number = _e; }
{ auto _e = room_number(); _o->room_number = _e; }
{ auto _e = position(); if (_e) _o->position = std::unique_ptr<TEN::Save::Vector3>(new TEN::Save::Vector3(*_e)); }
{ auto _e = rotation(); if (_e) _o->rotation = std::unique_ptr<TEN::Save::Vector4>(new TEN::Save::Vector4(*_e)); }
{ auto _e = scale(); if (_e) _o->scale = std::unique_ptr<TEN::Save::Vector3>(new TEN::Save::Vector3(*_e)); }
{ auto _e = state(); _o->state = _e; }
{ auto _e = triggerer(); _o->triggerer = _e; }
{ auto _e = timeout(); _o->timeout = _e; }
}
inline flatbuffers::Offset<VolumeState> VolumeState::Pack(flatbuffers::FlatBufferBuilder &_fbb, const VolumeStateT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
return CreateVolumeState(_fbb, _o, _rehasher);
}
inline flatbuffers::Offset<VolumeState> CreateVolumeState(flatbuffers::FlatBufferBuilder &_fbb, const VolumeStateT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
(void)_rehasher;
(void)_o;
struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const VolumeStateT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
auto _number = _o->number;
auto _room_number = _o->room_number;
auto _position = _o->position ? _o->position.get() : 0;
auto _rotation = _o->rotation ? _o->rotation.get() : 0;
auto _scale = _o->scale ? _o->scale.get() : 0;
auto _state = _o->state;
auto _triggerer = _o->triggerer;
auto _timeout = _o->timeout;
return TEN::Save::CreateVolumeState(
_fbb,
_number,
_room_number,
_position,
_rotation,
_scale,
_state,
_triggerer,
_timeout);
}
inline ScriptTableT *ScriptTable::UnPack(const flatbuffers::resolver_function_t *_resolver) const {
auto _o = std::make_unique<ScriptTableT>();
UnPackTo(_o.get(), _resolver);
@ -8470,6 +8846,8 @@ inline void SaveGame::UnPackTo(SaveGameT *_o, const flatbuffers::resolver_functi
{ auto _e = rope(); if (_e) _o->rope = std::unique_ptr<TEN::Save::RopeT>(_e->UnPack(_resolver)); }
{ auto _e = pendulum(); if (_e) _o->pendulum = std::unique_ptr<TEN::Save::PendulumT>(_e->UnPack(_resolver)); }
{ auto _e = alternate_pendulum(); if (_e) _o->alternate_pendulum = std::unique_ptr<TEN::Save::PendulumT>(_e->UnPack(_resolver)); }
{ auto _e = volume_states(); if (_e) { _o->volume_states.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->volume_states[_i] = std::unique_ptr<TEN::Save::VolumeStateT>(_e->Get(_i)->UnPack(_resolver)); } } }
{ auto _e = call_counters(); if (_e) { _o->call_counters.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->call_counters[_i] = std::unique_ptr<TEN::Save::EventSetCallCountersT>(_e->Get(_i)->UnPack(_resolver)); } } }
{ auto _e = script_vars(); if (_e) _o->script_vars = std::unique_ptr<TEN::Save::UnionVecT>(_e->UnPack(_resolver)); }
}
@ -8514,6 +8892,8 @@ inline flatbuffers::Offset<SaveGame> CreateSaveGame(flatbuffers::FlatBufferBuild
auto _rope = _o->rope ? CreateRope(_fbb, _o->rope.get(), _rehasher) : 0;
auto _pendulum = _o->pendulum ? CreatePendulum(_fbb, _o->pendulum.get(), _rehasher) : 0;
auto _alternate_pendulum = _o->alternate_pendulum ? CreatePendulum(_fbb, _o->alternate_pendulum.get(), _rehasher) : 0;
auto _volume_states = _fbb.CreateVector<flatbuffers::Offset<TEN::Save::VolumeState>> (_o->volume_states.size(), [](size_t i, _VectorArgs *__va) { return CreateVolumeState(*__va->__fbb, __va->__o->volume_states[i].get(), __va->__rehasher); }, &_va );
auto _call_counters = _fbb.CreateVector<flatbuffers::Offset<TEN::Save::EventSetCallCounters>> (_o->call_counters.size(), [](size_t i, _VectorArgs *__va) { return CreateEventSetCallCounters(*__va->__fbb, __va->__o->call_counters[i].get(), __va->__rehasher); }, &_va );
auto _script_vars = _o->script_vars ? CreateUnionVec(_fbb, _o->script_vars.get(), _rehasher) : 0;
return TEN::Save::CreateSaveGame(
_fbb,
@ -8550,6 +8930,8 @@ inline flatbuffers::Offset<SaveGame> CreateSaveGame(flatbuffers::FlatBufferBuild
_rope,
_pendulum,
_alternate_pendulum,
_volume_states,
_call_counters,
_script_vars);
}

View file

@ -275,9 +275,12 @@ table Sink {
}
table StaticMeshInfo {
number: int32;
room_number: int32;
position: Vector3;
rotation: Vector3;
color: Vector4;
hit_points: int32;
room_number: int32;
flags: int32;
}
@ -387,6 +390,23 @@ table Pendulum {
node: int32;
}
table EventSetCallCounters {
on_enter: int32;
on_inside: int32;
on_leave: int32;
}
table VolumeState {
number: int32;
room_number: int32;
position: Vector3;
rotation: Vector4;
scale: Vector3;
state: int32;
triggerer: int32;
timeout: int32;
}
struct KeyValPair {
key: uint32;
val: uint32;
@ -478,6 +498,8 @@ table SaveGame {
rope: Rope;
pendulum: Pendulum;
alternate_pendulum: Pendulum;
volume_states: [VolumeState];
call_counters: [EventSetCallCounters];
script_vars: UnionVec;
}

View file

@ -27,7 +27,7 @@
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<UseDebugLibraries>false</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v142</PlatformToolset>
</PropertyGroup>
@ -1055,7 +1055,7 @@ CALL gen.bat</Command>
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</DeploymentContent>
<FileType>Document</FileType>
</None>
<FxCompile Include="Shaders\DX11_Inventory.fx">
<None Include="Shaders\DX11_Inventory.fx">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild>
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</DeploymentContent>
@ -1067,8 +1067,8 @@ CALL gen.bat</Command>
<EntryPointName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">PS</EntryPointName>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Pixel</ShaderType>
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">4.1</ShaderModel>
</FxCompile>
<FxCompile Include="Shaders\DX11_Items.fx">
</None>
<None Include="Shaders\DX11_Items.fx">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild>
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</DeploymentContent>
@ -1080,8 +1080,8 @@ CALL gen.bat</Command>
<EntryPointName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">PS</EntryPointName>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Pixel</ShaderType>
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">4.1</ShaderModel>
</FxCompile>
<FxCompile Include="Shaders\DX11_Rooms.fx">
</None>
<None Include="Shaders\DX11_Rooms.fx">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild>
<DeploymentContent Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</DeploymentContent>
@ -1095,7 +1095,7 @@ CALL gen.bat</Command>
<ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Pixel</ShaderType>
<ShaderModel Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">4.1</ShaderModel>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">SHADOW_MAP_SIZE=512</PreprocessorDefinitions>
</FxCompile>
</None>
<None Include="Shaders\DX11_ShadowMap.fx">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild>