mirror of
https://github.com/TombEngine/TombEngine.git
synced 2025-04-28 15:57:59 +03:00
Merge
This commit is contained in:
parent
52aeee6022
commit
b37b4e8b55
72 changed files with 1302 additions and 638 deletions
|
@ -6,12 +6,14 @@ Version 1.1.1
|
|||
* Fix projectiles flying through animating objects.
|
||||
* Fix harpoon gun doing enormous damage on enemies.
|
||||
* Fix train death animation.
|
||||
* Fix zipline not following correct trajectory.
|
||||
* Fix TR1 wolf damage value inflicted on a close bite attack.
|
||||
* Fix TR1 bear various original AI issues.
|
||||
* Fix TR2 knife thrower AI.
|
||||
* Fix TR2 doberman crashing the game when killed by explosive weapons.
|
||||
* Fix volume change in settings not affecting voice track.
|
||||
* Fix several lighting bugs.
|
||||
* Fix savegame count not properly increasing.
|
||||
* Overhaul look mode:
|
||||
- Allow for consistent and wider viewing angles while crawling, crouching, and hanging.
|
||||
- Improve movement and control.
|
||||
|
@ -25,15 +27,20 @@ Version 1.1.1
|
|||
- A negative value requires a trigger to activate.
|
||||
|
||||
Lua API changes:
|
||||
* Add Flow::EnableLoadSave() function to disable savegames.
|
||||
* Add Flow::EnablePointFilter() function to disable bilinear filtering.
|
||||
* Add Lara::GetAmmoType() function to read the ammo that Lara is using.
|
||||
* Add Lara::GetControlLock() and Lara::SetControlLock() functions to handle controls locking.
|
||||
* Add Logic.HandleEvent() function to call node events.
|
||||
* Add functions to load, save, delete and check existence of savegames.
|
||||
* Add DisplayStringOption.RIGHT and DisplayStringOption.BLINK flags for DisplayString.
|
||||
* Make Vec2 object float-based instead of integer-based.
|
||||
* Add Vec2 arithmetic for division with a number and multiplication with another Vec2.
|
||||
* Add log messages warnings to functions AddCallback and RemoveCallback.
|
||||
* Fix InventoryItem constructor, now it will accept compound values in Item Action parameter.
|
||||
* Fix Moveable constructor forcing initial animation to 0 and hit points to 10, even if not specified.
|
||||
* Fix activation of a flipped room when using SetPos() script command or position change node.
|
||||
* Add extra parameter to GiveItem() function to optionally display an inventory item given to the player in the pickup summary.
|
||||
|
||||
Version 1.1.0
|
||||
==============
|
||||
|
|
|
@ -20,6 +20,10 @@ Flow.SetTotalSecretCount(5)
|
|||
|
||||
Flow.EnablePointFilter(false)
|
||||
|
||||
-- Enable/Disable saving and loading of savegames.
|
||||
|
||||
Flow.EnableLoadSave(true)
|
||||
|
||||
-- Disable/enable flycheat globally
|
||||
|
||||
Flow.EnableFlyCheat(true)
|
||||
|
|
|
@ -71,7 +71,7 @@ local strings =
|
|||
examine = { "Examine" },
|
||||
exit_game = { "Exit Game" },
|
||||
exit_to_title = { "Exit to Title" },
|
||||
general_actions = { "General Actions"},
|
||||
general_actions = { "General Actions" },
|
||||
high = { "High" },
|
||||
level_secrets_found = { "Secrets Found in Level" },
|
||||
load_game = { "Load Game" },
|
||||
|
@ -115,6 +115,7 @@ local strings =
|
|||
waiting_for_input = { "Waiting For Input" },
|
||||
window_title = { "TombEngine" },
|
||||
windowed = { "Windowed" },
|
||||
unlimited = { "Unlimited %s" },
|
||||
}
|
||||
|
||||
TEN.Flow.SetStrings(strings)
|
||||
|
|
|
@ -80,12 +80,13 @@ namespace TEN::Hud
|
|||
Life = std::max(Life, round(LIFE_BUFFER * FPS));
|
||||
}
|
||||
|
||||
void PickupSummaryController::AddDisplayPickup(GAME_OBJECT_ID objectID, const Vector3& targetPos)
|
||||
void PickupSummaryController::AddDisplayPickup(GAME_OBJECT_ID objectID, const Vector2& origin, unsigned int count)
|
||||
{
|
||||
constexpr auto STRING_SCALAR_MAX = 0.6f;
|
||||
|
||||
// TODO: Call this elsewhere, maybe in pickup.cpp. -- Sezz 2023.02.06
|
||||
PickedUpObject(objectID);
|
||||
// No count; return early.
|
||||
if (count == 0)
|
||||
return;
|
||||
|
||||
float life = round(DisplayPickup::LIFE_MAX * FPS);
|
||||
|
||||
|
@ -98,7 +99,7 @@ namespace TEN::Hud
|
|||
|
||||
if (pickup.ObjectID == objectID)
|
||||
{
|
||||
pickup.Count++;
|
||||
pickup.Count += count;
|
||||
pickup.Life = life;
|
||||
pickup.StringScalar = STRING_SCALAR_MAX;
|
||||
return;
|
||||
|
@ -108,14 +109,10 @@ namespace TEN::Hud
|
|||
// Create new display pickup.
|
||||
auto& pickup = GetNewDisplayPickup();
|
||||
|
||||
auto origin = g_Renderer.Get2DPosition(targetPos);
|
||||
if (!origin.has_value())
|
||||
origin = Vector2::Zero;
|
||||
|
||||
pickup.ObjectID = objectID;
|
||||
pickup.Count = 1;
|
||||
pickup.Count = count;
|
||||
pickup.Position =
|
||||
pickup.Origin = *origin;
|
||||
pickup.Origin = origin;
|
||||
pickup.Target = Vector2::Zero;
|
||||
pickup.Life = life;
|
||||
pickup.Scale = 0.0f;
|
||||
|
@ -125,6 +122,14 @@ namespace TEN::Hud
|
|||
pickup.StringScalar = 0.0f;
|
||||
}
|
||||
|
||||
void PickupSummaryController::AddDisplayPickup(GAME_OBJECT_ID objectID, const Vector3& pos, unsigned int count)
|
||||
{
|
||||
// Project 3D position to 2D origin.
|
||||
auto origin = g_Renderer.Get2DPosition(pos);
|
||||
|
||||
AddDisplayPickup(objectID, origin.value_or(Vector2::Zero), count);
|
||||
}
|
||||
|
||||
void PickupSummaryController::Update()
|
||||
{
|
||||
if (DisplayPickups.empty())
|
||||
|
@ -176,14 +181,14 @@ namespace TEN::Hud
|
|||
constexpr auto SCREEN_SCALE = Vector2(SCREEN_SPACE_RES.x * SCREEN_SCALE_COEFF, SCREEN_SPACE_RES.y * SCREEN_SCALE_COEFF);
|
||||
constexpr auto SCREEN_OFFSET = Vector2(SCREEN_SPACE_RES.y * SCREEN_OFFSET_COEFF);
|
||||
|
||||
// Calculate positions.
|
||||
// Calculate stack positions.
|
||||
auto stackPositions = std::vector<Vector2>{};
|
||||
stackPositions.resize(DisplayPickups.size());
|
||||
for (int i = 0; i < DisplayPickups.size(); i++)
|
||||
{
|
||||
auto relPos = (i < STACK_HEIGHT_MAX) ? (Vector2(0.0f, i) * SCREEN_SCALE) : Vector2(0.0f, SCREEN_SPACE_RES.y);
|
||||
auto pos = (SCREEN_SPACE_RES - relPos) - SCREEN_OFFSET;
|
||||
stackPositions[i] = (pos);
|
||||
stackPositions[i] = pos;
|
||||
}
|
||||
|
||||
return stackPositions;
|
||||
|
@ -191,6 +196,8 @@ namespace TEN::Hud
|
|||
|
||||
DisplayPickup& PickupSummaryController::GetNewDisplayPickup()
|
||||
{
|
||||
assertion(DisplayPickups.size() <= DISPLAY_PICKUP_COUNT_MAX, "Display pickup overflow.");
|
||||
|
||||
// Add and return new display pickup.
|
||||
if (DisplayPickups.size() < DISPLAY_PICKUP_COUNT_MAX)
|
||||
return DisplayPickups.emplace_back();
|
||||
|
@ -212,7 +219,6 @@ namespace TEN::Hud
|
|||
|
||||
void PickupSummaryController::DrawDebug() const
|
||||
{
|
||||
g_Renderer.PrintDebugMessage("PICKUP SUMMARY DEBUG");
|
||||
g_Renderer.PrintDebugMessage("Display pickups: %d", DisplayPickups.size());
|
||||
g_Renderer.PrintDebugMessage("Display pickups in summary: %d", DisplayPickups.size());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,14 +33,16 @@ namespace TEN::Hud
|
|||
{
|
||||
private:
|
||||
// Constants
|
||||
static constexpr auto DISPLAY_PICKUP_COUNT_MAX = 64;
|
||||
static constexpr auto DISPLAY_PICKUP_COUNT_MAX = 64;
|
||||
static constexpr auto DISPLAY_PICKUP_COUNT_ARG_DEFAULT = 1;
|
||||
|
||||
// Members
|
||||
std::vector<DisplayPickup> DisplayPickups = {};
|
||||
|
||||
public:
|
||||
// Utilities
|
||||
void AddDisplayPickup(GAME_OBJECT_ID objectID, const Vector3& targetPos);
|
||||
void AddDisplayPickup(GAME_OBJECT_ID objectID, const Vector2& origin, unsigned int count = DISPLAY_PICKUP_COUNT_ARG_DEFAULT);
|
||||
void AddDisplayPickup(GAME_OBJECT_ID objectID, const Vector3& pos, unsigned int count = DISPLAY_PICKUP_COUNT_ARG_DEFAULT);
|
||||
|
||||
void Update();
|
||||
void Draw() const;
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
#include "Game/Hud/TargetHighlighter.h"
|
||||
|
||||
#include "Game/camera.h"
|
||||
#include "Game/effects/DisplaySprite.h"
|
||||
#include "Game/items.h"
|
||||
#include "Game/effects/ScreenSprite.h"
|
||||
#include "Game/lara/lara_fire.h"
|
||||
#include "Game/lara/lara_helpers.h"
|
||||
#include "Math/Math.h"
|
||||
|
@ -11,7 +11,7 @@
|
|||
#include "Specific/configuration.h"
|
||||
#include "Specific/trutils.h"
|
||||
|
||||
using namespace TEN::Effects::ScreenSprite;
|
||||
using namespace TEN::Effects::DisplaySprite;
|
||||
using namespace TEN::Math;
|
||||
using namespace TEN::Utils;
|
||||
using TEN::Renderer::g_Renderer;
|
||||
|
@ -196,19 +196,22 @@ namespace TEN::Hud
|
|||
if (crosshair.IsOffscreen())
|
||||
continue;
|
||||
|
||||
AddScreenSprite(
|
||||
AddDisplaySprite(
|
||||
ID_CROSSHAIR, CROSSHAIR_SPRITE_STATIC_ELEMENT_INDEX,
|
||||
crosshair.Position, crosshair.Orientation,
|
||||
Vector2(crosshair.Size), crosshair.Color, 0, BLEND_MODES::BLENDMODE_ALPHABLEND);
|
||||
crosshair.Position, crosshair.Orientation, Vector2(crosshair.Size), crosshair.Color,
|
||||
0, DisplaySpriteAlignMode::Center, DisplaySpriteScaleMode::Fit, BLEND_MODES::BLENDMODE_ALPHABLEND);
|
||||
|
||||
if (crosshair.RadiusScale > EPSILON)
|
||||
{
|
||||
for (const auto& segment : crosshair.Segments)
|
||||
{
|
||||
AddScreenSprite(
|
||||
short orient = crosshair.Orientation + segment.OrientOffset;
|
||||
auto scale = Vector2(crosshair.Size / 2);
|
||||
|
||||
AddDisplaySprite(
|
||||
ID_CROSSHAIR, CROSSHAIR_SPRITE_SEGMENT_ELEMENT_INDEX,
|
||||
crosshair.Position + segment.PosOffset, crosshair.Orientation + segment.OrientOffset,
|
||||
Vector2(crosshair.Size / 2), crosshair.Color, 0, BLEND_MODES::BLENDMODE_ALPHABLEND);
|
||||
crosshair.Position + segment.PosOffset, orient, scale, crosshair.Color,
|
||||
0, DisplaySpriteAlignMode::Center, DisplaySpriteScaleMode::Fit, BLEND_MODES::BLENDMODE_ALPHABLEND);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "Game/effects/debris.h"
|
||||
#include "Game/effects/Blood.h"
|
||||
#include "Game/effects/Bubble.h"
|
||||
#include "Game/effects/DisplaySprite.h"
|
||||
#include "Game/effects/Drip.h"
|
||||
#include "Game/effects/effects.h"
|
||||
#include "Game/effects/Electricity.h"
|
||||
|
@ -20,7 +21,6 @@
|
|||
#include "Game/effects/Footprint.h"
|
||||
#include "Game/effects/Hair.h"
|
||||
#include "Game/effects/Ripple.h"
|
||||
#include "Game/effects/ScreenSprite.h"
|
||||
#include "Game/effects/simple_particle.h"
|
||||
#include "Game/effects/smoke.h"
|
||||
#include "Game/effects/spark.h"
|
||||
|
@ -63,6 +63,7 @@ using namespace std::chrono;
|
|||
using namespace TEN::Effects;
|
||||
using namespace TEN::Effects::Blood;
|
||||
using namespace TEN::Effects::Bubble;
|
||||
using namespace TEN::Effects::DisplaySprite;
|
||||
using namespace TEN::Effects::Drip;
|
||||
using namespace TEN::Effects::Electricity;
|
||||
using namespace TEN::Effects::Environment;
|
||||
|
@ -70,7 +71,6 @@ using namespace TEN::Effects::Explosion;
|
|||
using namespace TEN::Effects::Footprint;
|
||||
using namespace TEN::Effects::Hair;
|
||||
using namespace TEN::Effects::Ripple;
|
||||
using namespace TEN::Effects::ScreenSprite;
|
||||
using namespace TEN::Effects::Smoke;
|
||||
using namespace TEN::Effects::Spark;
|
||||
using namespace TEN::Effects::Streamer;
|
||||
|
@ -95,7 +95,7 @@ bool ThreadEnded;
|
|||
|
||||
int RequiredStartPos;
|
||||
int CurrentLevel;
|
||||
int LevelComplete;
|
||||
int NextLevel;
|
||||
|
||||
int SystemNameHash = 0;
|
||||
|
||||
|
@ -120,6 +120,9 @@ int DrawPhase(bool isTitle)
|
|||
g_Renderer.Render();
|
||||
}
|
||||
|
||||
// Clear display sprites.
|
||||
ClearDisplaySprites();
|
||||
|
||||
Camera.numberFrames = g_Renderer.Synchronize();
|
||||
return Camera.numberFrames;
|
||||
}
|
||||
|
@ -147,8 +150,6 @@ GameStatus ControlPhase(int numFrames)
|
|||
|
||||
for (framesCount += numFrames; framesCount > 0; framesCount -= 2)
|
||||
{
|
||||
ClearScreenSprites();
|
||||
|
||||
// Controls are polled before OnControlPhase, so input data could be
|
||||
// overwritten by script API methods.
|
||||
HandleControls(isTitle);
|
||||
|
@ -420,11 +421,11 @@ void CleanUp()
|
|||
StreamerEffect.Clear();
|
||||
ClearUnderwaterBloodParticles();
|
||||
ClearBubbles();
|
||||
ClearDisplaySprites();
|
||||
ClearFootprints();
|
||||
ClearDrips();
|
||||
ClearRipples();
|
||||
ClearLaserBarrierEffects();
|
||||
ClearScreenSprites();
|
||||
DisableSmokeParticles();
|
||||
DisableSparkParticles();
|
||||
DisableDebris();
|
||||
|
@ -619,16 +620,20 @@ GameStatus HandleMenuCalls(bool isTitle)
|
|||
|
||||
// Does the player want to enter inventory?
|
||||
if (IsClicked(In::Save) && LaraItem->HitPoints > 0 &&
|
||||
g_Gui.GetInventoryMode() != InventoryMode::Save)
|
||||
g_Gui.GetInventoryMode() != InventoryMode::Save &&
|
||||
g_GameFlow->IsLoadSaveEnabled())
|
||||
{
|
||||
SaveGame::LoadSavegameInfos();
|
||||
g_Gui.SetInventoryMode(InventoryMode::Save);
|
||||
|
||||
if (g_Gui.CallInventory(LaraItem, false))
|
||||
result = GameStatus::SaveGame;
|
||||
}
|
||||
else if (IsClicked(In::Load) &&
|
||||
g_Gui.GetInventoryMode() != InventoryMode::Load)
|
||||
g_Gui.GetInventoryMode() != InventoryMode::Load &&
|
||||
g_GameFlow->IsLoadSaveEnabled())
|
||||
{
|
||||
SaveGame::LoadSavegameInfos();
|
||||
g_Gui.SetInventoryMode(InventoryMode::Load);
|
||||
|
||||
if (g_Gui.CallInventory(LaraItem, false))
|
||||
|
@ -673,8 +678,16 @@ GameStatus HandleGlobalInputEvents(bool isTitle)
|
|||
}
|
||||
|
||||
// Check if level has been completed.
|
||||
if (LevelComplete)
|
||||
// Negative NextLevel indicates that a savegame must be loaded from corresponding slot.
|
||||
if (NextLevel > 0)
|
||||
{
|
||||
return GameStatus::LevelComplete;
|
||||
}
|
||||
else if (NextLevel < 0)
|
||||
{
|
||||
g_GameFlow->SelectedSaveGame = -(NextLevel + 1);
|
||||
return GameStatus::LoadGame;
|
||||
}
|
||||
|
||||
return GameStatus::None;
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ extern bool ThreadEnded;
|
|||
|
||||
extern int RequiredStartPos;
|
||||
extern int CurrentLevel;
|
||||
extern int LevelComplete;
|
||||
extern int NextLevel;
|
||||
extern int SystemNameHash;
|
||||
|
||||
extern bool InItemControlLoop;
|
||||
|
|
|
@ -332,7 +332,7 @@ void Turn180(ItemInfo* item)
|
|||
|
||||
void FinishLevel(ItemInfo* item)
|
||||
{
|
||||
LevelComplete = CurrentLevel + 1;
|
||||
NextLevel = CurrentLevel + 1;
|
||||
}
|
||||
|
||||
void VoidEffect(ItemInfo* item)
|
||||
|
|
|
@ -751,7 +751,7 @@ void TestTriggers(int x, int y, int z, FloorInfo* floor, VolumeActivator activat
|
|||
|
||||
case TO_FINISH:
|
||||
RequiredStartPos = false;
|
||||
LevelComplete = CurrentLevel + 1;
|
||||
NextLevel = CurrentLevel + 1;
|
||||
break;
|
||||
|
||||
case TO_CD:
|
||||
|
@ -785,20 +785,14 @@ void TestTriggers(int x, int y, int z, FloorInfo* floor, VolumeActivator activat
|
|||
if (!((int)set.Activators & activatorType))
|
||||
continue;
|
||||
|
||||
switch (trigger & TIMER_BITS)
|
||||
int eventType = trigger & TIMER_BITS;
|
||||
if (eventType >= (int)VolumeEventType::Count)
|
||||
{
|
||||
case 0:
|
||||
HandleEvent(set.OnEnter, activator);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
HandleEvent(set.OnInside, activator);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
HandleEvent(set.OnLeave, activator);
|
||||
break;
|
||||
TENLog("Unknown volume event type encountered for legacy trigger " + std::to_string(eventType), LogLevel::Warning);
|
||||
continue;
|
||||
}
|
||||
|
||||
HandleEvent(set.Events[eventType], activator);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -66,6 +66,35 @@ namespace TEN::Control::Volumes
|
|||
event.CallCounter--;
|
||||
}
|
||||
|
||||
bool HandleEvent(const std::string& name, VolumeEventType eventType, VolumeActivator activator)
|
||||
{
|
||||
// Cache last used event sets so that whole list is not searched every time user calls this.
|
||||
static VolumeEventSet* lastEventSetPtr = nullptr;
|
||||
|
||||
if (lastEventSetPtr != nullptr && lastEventSetPtr->Name != name)
|
||||
lastEventSetPtr = nullptr;
|
||||
|
||||
if (lastEventSetPtr == nullptr)
|
||||
{
|
||||
for (auto& eventSet : g_Level.EventSets)
|
||||
{
|
||||
if (eventSet.Name == name)
|
||||
{
|
||||
lastEventSetPtr = &eventSet;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (lastEventSetPtr != nullptr)
|
||||
{
|
||||
HandleEvent(lastEventSetPtr->Events[(int)eventType], activator);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void TestVolumes(short roomNumber, const BoundingOrientedBox& box, VolumeActivatorFlags activatorFlag, VolumeActivator activator)
|
||||
{
|
||||
if (roomNumber == NO_ROOM)
|
||||
|
@ -120,14 +149,14 @@ namespace TEN::Control::Volumes
|
|||
GameTimer
|
||||
});
|
||||
|
||||
HandleEvent(set.OnEnter, activator);
|
||||
HandleEvent(set.Events[(int)VolumeEventType::Enter], activator);
|
||||
}
|
||||
else
|
||||
{
|
||||
entryPtr->Status = VolumeStateStatus::Inside;
|
||||
entryPtr->Timestamp = GameTimer;
|
||||
|
||||
HandleEvent(set.OnInside, activator);
|
||||
HandleEvent(set.Events[(int)VolumeEventType::Inside], activator);
|
||||
}
|
||||
}
|
||||
else if (entryPtr != nullptr)
|
||||
|
@ -140,7 +169,7 @@ namespace TEN::Control::Volumes
|
|||
entryPtr->Status = VolumeStateStatus::Leaving;
|
||||
entryPtr->Timestamp = GameTimer;
|
||||
|
||||
HandleEvent(set.OnLeave, activator);
|
||||
HandleEvent(set.Events[(int)VolumeEventType::Leave], activator);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -223,21 +252,24 @@ namespace TEN::Control::Volumes
|
|||
unsigned int nodeCount = 0;
|
||||
for (const auto& set : g_Level.EventSets)
|
||||
{
|
||||
if ((set.OnEnter.Mode == VolumeEventMode::Nodes) && !set.OnEnter.Data.empty())
|
||||
if ((set.Events[(int)VolumeEventType::Enter].Mode == VolumeEventMode::Nodes) &&
|
||||
!set.Events[(int)VolumeEventType::Enter].Data.empty())
|
||||
{
|
||||
g_GameScript->ExecuteString(set.OnEnter.Data);
|
||||
g_GameScript->ExecuteString(set.Events[(int)VolumeEventType::Enter].Data);
|
||||
nodeCount++;
|
||||
}
|
||||
|
||||
if ((set.OnInside.Mode == VolumeEventMode::Nodes) && !set.OnInside.Data.empty())
|
||||
if ((set.Events[(int)VolumeEventType::Inside].Mode == VolumeEventMode::Nodes) &&
|
||||
!set.Events[(int)VolumeEventType::Inside].Data.empty())
|
||||
{
|
||||
g_GameScript->ExecuteString(set.OnInside.Data);
|
||||
g_GameScript->ExecuteString(set.Events[(int)VolumeEventType::Inside].Data);
|
||||
nodeCount++;
|
||||
}
|
||||
|
||||
if ((set.OnLeave.Mode == VolumeEventMode::Nodes) && !set.OnLeave.Data.empty())
|
||||
if ((set.Events[(int)VolumeEventType::Leave].Mode == VolumeEventMode::Nodes) &&
|
||||
!set.Events[(int)VolumeEventType::Leave].Data.empty())
|
||||
{
|
||||
g_GameScript->ExecuteString(set.OnLeave.Data);
|
||||
g_GameScript->ExecuteString(set.Events[(int)VolumeEventType::Leave].Data);
|
||||
nodeCount++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,6 +44,7 @@ namespace TEN::Control::Volumes
|
|||
void TestVolumes(CAMERA_INFO* camera);
|
||||
|
||||
void HandleEvent(VolumeEvent& event, VolumeActivator& activator);
|
||||
bool HandleEvent(const std::string& name, VolumeEventType eventType, VolumeActivator activator);
|
||||
void InitializeNodeScripts();
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,15 @@ namespace TEN::Control::Volumes
|
|||
Nodes
|
||||
};
|
||||
|
||||
enum class VolumeEventType
|
||||
{
|
||||
Enter,
|
||||
Inside,
|
||||
Leave,
|
||||
|
||||
Count
|
||||
};
|
||||
|
||||
enum class VolumeActivatorFlags
|
||||
{
|
||||
None = (0 << 0),
|
||||
|
@ -42,11 +51,8 @@ namespace TEN::Control::Volumes
|
|||
|
||||
struct VolumeEventSet
|
||||
{
|
||||
std::string Name = {};
|
||||
std::string Name = {};
|
||||
VolumeActivatorFlags Activators = VolumeActivatorFlags::None;
|
||||
|
||||
VolumeEvent OnEnter = {};
|
||||
VolumeEvent OnLeave = {};
|
||||
VolumeEvent OnInside = {};
|
||||
std::array<VolumeEvent, int(VolumeEventType::Count)> Events = {};
|
||||
};
|
||||
};
|
||||
|
|
38
TombEngine/Game/effects/DisplaySprite.cpp
Normal file
38
TombEngine/Game/effects/DisplaySprite.cpp
Normal file
|
@ -0,0 +1,38 @@
|
|||
#include "framework.h"
|
||||
#include "Game/effects/DisplaySprite.h"
|
||||
|
||||
#include "Game/effects/effects.h"
|
||||
#include "Game/Setup.h"
|
||||
#include "Math/Math.h"
|
||||
#include "Objects/objectslist.h"
|
||||
#include "Renderer/Renderer11.h"
|
||||
|
||||
using namespace TEN::Math;
|
||||
|
||||
namespace TEN::Effects::DisplaySprite
|
||||
{
|
||||
std::vector<DisplaySprite> DisplaySprites = {};
|
||||
|
||||
void AddDisplaySprite(GAME_OBJECT_ID objectID, int spriteID, const Vector2& pos, short orient, const Vector2& scale, const Vector4& color,
|
||||
int priority, DisplaySpriteAlignMode alignMode, DisplaySpriteScaleMode scaleMode, BLEND_MODES blendMode)
|
||||
{
|
||||
auto displaySprite = DisplaySprite{};
|
||||
displaySprite.ObjectID = objectID;
|
||||
displaySprite.SpriteID = spriteID;
|
||||
displaySprite.Position = pos;
|
||||
displaySprite.Orientation = orient;
|
||||
displaySprite.Scale = scale;
|
||||
displaySprite.Color = color;
|
||||
displaySprite.Priority = priority;
|
||||
displaySprite.AlignMode = alignMode;
|
||||
displaySprite.ScaleMode = scaleMode;
|
||||
displaySprite.BlendMode = blendMode;
|
||||
|
||||
DisplaySprites.push_back(displaySprite);
|
||||
}
|
||||
|
||||
void ClearDisplaySprites()
|
||||
{
|
||||
DisplaySprites.clear();
|
||||
}
|
||||
}
|
48
TombEngine/Game/effects/DisplaySprite.h
Normal file
48
TombEngine/Game/effects/DisplaySprite.h
Normal file
|
@ -0,0 +1,48 @@
|
|||
#pragma once
|
||||
#include "Objects/game_object_ids.h"
|
||||
#include "Renderer/Renderer11Enums.h"
|
||||
|
||||
namespace TEN::Effects::DisplaySprite
|
||||
{
|
||||
enum class DisplaySpriteAlignMode
|
||||
{
|
||||
Center,
|
||||
CenterTop,
|
||||
CenterBottom,
|
||||
CenterLeft,
|
||||
CenterRight,
|
||||
TopLeft,
|
||||
TopRight,
|
||||
BottomLeft,
|
||||
BottomRight
|
||||
};
|
||||
|
||||
enum class DisplaySpriteScaleMode
|
||||
{
|
||||
Fit,
|
||||
Fill,
|
||||
Stretch
|
||||
};
|
||||
|
||||
struct DisplaySprite
|
||||
{
|
||||
GAME_OBJECT_ID ObjectID = ID_DEFAULT_SPRITES;
|
||||
int SpriteID = 0;
|
||||
|
||||
Vector2 Position = Vector2::Zero;
|
||||
short Orientation = 0;
|
||||
Vector2 Scale = Vector2::One;
|
||||
Vector4 Color = Vector4::One;
|
||||
|
||||
int Priority = 0;
|
||||
DisplaySpriteAlignMode AlignMode = DisplaySpriteAlignMode::Center;
|
||||
DisplaySpriteScaleMode ScaleMode = DisplaySpriteScaleMode::Fit;
|
||||
BLEND_MODES BlendMode = BLENDMODE_ALPHABLEND;
|
||||
};
|
||||
|
||||
extern std::vector<DisplaySprite> DisplaySprites;
|
||||
|
||||
void AddDisplaySprite(GAME_OBJECT_ID objectID, int spriteID, const Vector2& pos, short orient, const Vector2& scale, const Vector4& color,
|
||||
int priority, DisplaySpriteAlignMode alignMode, DisplaySpriteScaleMode scaleMode, BLEND_MODES blendMode);
|
||||
void ClearDisplaySprites();
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
#include "framework.h"
|
||||
#include "Game/effects/ScreenSprite.h"
|
||||
|
||||
#include "Game/effects/effects.h"
|
||||
#include "Game/Setup.h"
|
||||
#include "Math/Math.h"
|
||||
#include "Objects/objectslist.h"
|
||||
#include "Renderer/Renderer11.h"
|
||||
|
||||
using namespace TEN::Math;
|
||||
|
||||
namespace TEN::Effects::ScreenSprite
|
||||
{
|
||||
std::vector<ScreenSprite> ScreenSprites = {};
|
||||
|
||||
void AddScreenSprite(GAME_OBJECT_ID objectID, int spriteIndex, const Vector2& pos, short orient, const Vector2& size,
|
||||
const Vector4& color, int priority, BLEND_MODES blendMode)
|
||||
{
|
||||
auto screenSprite = ScreenSprite{};
|
||||
|
||||
screenSprite.ObjectID = objectID;
|
||||
screenSprite.SpriteIndex = spriteIndex;
|
||||
screenSprite.Position = pos;
|
||||
screenSprite.Orientation = orient;
|
||||
screenSprite.Size = size;
|
||||
screenSprite.Color = color;
|
||||
screenSprite.Priority = priority;
|
||||
screenSprite.BlendMode = blendMode;
|
||||
|
||||
ScreenSprites.push_back(screenSprite);
|
||||
}
|
||||
|
||||
void ClearScreenSprites()
|
||||
{
|
||||
ScreenSprites.clear();
|
||||
}
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
#pragma once
|
||||
#include "Objects/game_object_ids.h"
|
||||
#include "Renderer/Renderer11Enums.h"
|
||||
|
||||
namespace TEN::Effects::ScreenSprite
|
||||
{
|
||||
struct ScreenSprite
|
||||
{
|
||||
GAME_OBJECT_ID ObjectID = ID_DEFAULT_SPRITES;
|
||||
int SpriteIndex = 0;
|
||||
|
||||
Vector2 Position = Vector2::Zero;
|
||||
short Orientation = 0;
|
||||
Vector2 Size = Vector2::One;
|
||||
Vector4 Color = Vector4::One;
|
||||
|
||||
int Priority = 0;
|
||||
BLEND_MODES BlendMode = BLENDMODE_ALPHABLEND;
|
||||
};
|
||||
|
||||
extern std::vector<ScreenSprite> ScreenSprites;
|
||||
|
||||
void AddScreenSprite(GAME_OBJECT_ID objectID, int spriteIndex, const Vector2& pos, short orient, const Vector2& size,
|
||||
const Vector4& color, int priority, BLEND_MODES blendMode);
|
||||
void ClearScreenSprites();
|
||||
}
|
|
@ -181,7 +181,7 @@ namespace TEN::Gui
|
|||
return false;
|
||||
|
||||
// Avoid Select or Action release interference when entering inventory.
|
||||
if (GetActionTimeActive(In::Select) < TimeInMenu || GetActionTimeActive(In::Action) < TimeInMenu)
|
||||
if (GetActionTimeActive(In::Select) < TimeInMenu && GetActionTimeActive(In::Action) < TimeInMenu)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
@ -202,7 +202,7 @@ namespace TEN::Gui
|
|||
return Rings[(int)ringType];
|
||||
}
|
||||
|
||||
short GuiController::GetSelectedOption()
|
||||
int GuiController::GetSelectedOption()
|
||||
{
|
||||
return SelectedOption;
|
||||
}
|
||||
|
@ -295,7 +295,7 @@ namespace TEN::Gui
|
|||
switch (MenuToDisplay)
|
||||
{
|
||||
case Menu::Title:
|
||||
OptionCount = numTitleOptions;
|
||||
OptionCount = g_GameFlow->IsLoadSaveEnabled() ? numTitleOptions : (numTitleOptions - 1);
|
||||
break;
|
||||
|
||||
case Menu::SelectLevel:
|
||||
|
@ -378,7 +378,12 @@ namespace TEN::Gui
|
|||
|
||||
if (MenuToDisplay == Menu::Title)
|
||||
{
|
||||
switch (SelectedOption)
|
||||
// Skip load game entry if loading and saving is disabled.
|
||||
int realSelectedOption = SelectedOption;
|
||||
if (!g_GameFlow->IsLoadSaveEnabled() && SelectedOption > TitleOption::NewGame)
|
||||
realSelectedOption++;
|
||||
|
||||
switch (realSelectedOption)
|
||||
{
|
||||
case TitleOption::NewGame:
|
||||
if (g_GameFlow->IsLevelSelectEnabled())
|
||||
|
@ -388,7 +393,9 @@ namespace TEN::Gui
|
|||
MenuToDisplay = Menu::SelectLevel;
|
||||
}
|
||||
else
|
||||
{
|
||||
inventoryResult = InventoryResult::NewGame;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
|
@ -396,6 +403,7 @@ namespace TEN::Gui
|
|||
selectedOptionBackup = SelectedOption;
|
||||
SelectedOption = 0;
|
||||
MenuToDisplay = Menu::LoadGame;
|
||||
SaveGame::LoadSavegameInfos();
|
||||
break;
|
||||
|
||||
case TitleOption::Options:
|
||||
|
@ -1687,7 +1695,7 @@ namespace TEN::Gui
|
|||
if (lara->Inventory.Diary.Present)
|
||||
InsertObjectIntoList(INV_OBJECT_DIARY);
|
||||
|
||||
if (g_GameFlow->EnableLoadSave)
|
||||
if (g_GameFlow->IsLoadSaveEnabled())
|
||||
{
|
||||
InsertObjectIntoList(INV_OBJECT_LOAD_FLOPPY);
|
||||
InsertObjectIntoList(INV_OBJECT_SAVE_FLOPPY);
|
||||
|
@ -2539,12 +2547,12 @@ namespace TEN::Gui
|
|||
break;
|
||||
|
||||
case MenuType::Load:
|
||||
// fill_up_savegames_array // Maybe not?
|
||||
SaveGame::LoadSavegameInfos();
|
||||
SetInventoryMode(InventoryMode::Load);
|
||||
break;
|
||||
|
||||
case MenuType::Save:
|
||||
// fill_up_savegames_array
|
||||
SaveGame::LoadSavegameInfos();
|
||||
SetInventoryMode(InventoryMode::Save);
|
||||
break;
|
||||
|
||||
|
@ -2709,7 +2717,7 @@ namespace TEN::Gui
|
|||
|
||||
if (AmmoObjectList[n].Amount == -1)
|
||||
{
|
||||
sprintf(&invTextBuffer[0], "Unlimited %s", g_GameFlow->GetString(InventoryObjectTable[AmmoObjectList[n].InventoryItem].ObjectName));
|
||||
sprintf(&invTextBuffer[0], g_GameFlow->GetString(STRING_UNLIMITED), g_GameFlow->GetString(InventoryObjectTable[AmmoObjectList[n].InventoryItem].ObjectName));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -3032,7 +3040,7 @@ namespace TEN::Gui
|
|||
{
|
||||
if (numItems == -1)
|
||||
{
|
||||
sprintf(textBuffer, "Unlimited %s", g_GameFlow->GetString(invObject.ObjectName));
|
||||
sprintf(textBuffer, g_GameFlow->GetString(STRING_UNLIMITED), g_GameFlow->GetString(invObject.ObjectName));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -3393,7 +3401,7 @@ namespace TEN::Gui
|
|||
}
|
||||
}
|
||||
|
||||
short GuiController::GetLoadSaveSelection()
|
||||
int GuiController::GetLoadSaveSelection()
|
||||
{
|
||||
return SelectedSaveSlot;
|
||||
}
|
||||
|
@ -3463,7 +3471,6 @@ namespace TEN::Gui
|
|||
if (GuiIsSelected())
|
||||
{
|
||||
SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always);
|
||||
g_GameScript->OnSave();
|
||||
SaveGame::Save(SelectedSaveSlot);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -133,7 +133,7 @@ namespace TEN::Gui
|
|||
int OptionCount;
|
||||
int SelectedSaveSlot;
|
||||
|
||||
float TimeInMenu = 0.0f;
|
||||
float TimeInMenu = -1.0f;
|
||||
SettingsData CurrentSettings;
|
||||
|
||||
// Inventory variables
|
||||
|
@ -183,14 +183,14 @@ namespace TEN::Gui
|
|||
|
||||
// Getters
|
||||
const InventoryRing& GetRing(RingTypes ringType);
|
||||
short GetSelectedOption();
|
||||
int GetSelectedOption();
|
||||
Menu GetMenuToDisplay();
|
||||
InventoryMode GetInventoryMode();
|
||||
int GetInventoryItemChosen();
|
||||
int GetEnterInventory();
|
||||
int GetLastInventoryItem();
|
||||
SettingsData& GetCurrentSettings();
|
||||
short GetLoadSaveSelection();
|
||||
int GetLoadSaveSelection();
|
||||
|
||||
// Setters
|
||||
void SetSelectedOption(int menu);
|
||||
|
|
|
@ -203,6 +203,7 @@ void CollectCarriedItems(ItemInfo* item)
|
|||
{
|
||||
auto* pickupItem = &g_Level.Items[pickupNumber];
|
||||
|
||||
PickedUpObject(pickupItem->ObjectNumber);
|
||||
g_Hud.PickupSummary.AddDisplayPickup(pickupItem->ObjectNumber, pickupItem->Pose.Position.ToVector3());
|
||||
KillItem(pickupNumber);
|
||||
|
||||
|
@ -248,7 +249,9 @@ void CollectMultiplePickups(int itemNumber)
|
|||
continue;
|
||||
}
|
||||
|
||||
PickedUpObject(currentItem->ObjectNumber);
|
||||
g_Hud.PickupSummary.AddDisplayPickup(currentItem->ObjectNumber, currentItem->Pose.Position.ToVector3());
|
||||
|
||||
if (currentItem->TriggerFlags & (1 << 8))
|
||||
{
|
||||
for (int i = 0; i < g_Level.NumItems; i++)
|
||||
|
@ -282,7 +285,9 @@ void DoPickup(ItemInfo* laraItem)
|
|||
|
||||
if (pickupItem->ObjectNumber == ID_BURNING_TORCH_ITEM)
|
||||
{
|
||||
PickedUpObject(ID_BURNING_TORCH_ITEM);
|
||||
g_Hud.PickupSummary.AddDisplayPickup(ID_BURNING_TORCH_ITEM, pickupItem->Pose.Position.ToVector3());
|
||||
|
||||
GetFlameTorch();
|
||||
lara->Torch.IsLit = (pickupItem->ItemFlags[3] & 1);
|
||||
|
||||
|
@ -318,6 +323,7 @@ void DoPickup(ItemInfo* laraItem)
|
|||
return;
|
||||
}
|
||||
|
||||
PickedUpObject(pickupItem->ObjectNumber);
|
||||
g_Hud.PickupSummary.AddDisplayPickup(pickupItem->ObjectNumber, pickupItem->Pose.Position.ToVector3());
|
||||
HideOrDisablePickup(*pickupItem);
|
||||
|
||||
|
@ -329,9 +335,11 @@ void DoPickup(ItemInfo* laraItem)
|
|||
{
|
||||
if (laraItem->Animation.AnimNumber == LA_CROWBAR_PRY_WALL_SLOW)
|
||||
{
|
||||
PickedUpObject(ID_CROWBAR_ITEM);
|
||||
g_Hud.PickupSummary.AddDisplayPickup(ID_CROWBAR_ITEM, pickupItem->Pose.Position.ToVector3());
|
||||
lara->Inventory.HasCrowbar = true;
|
||||
KillItem(pickupItemNumber);
|
||||
|
||||
lara->Inventory.HasCrowbar = true;
|
||||
}
|
||||
else if (laraItem->Animation.ActiveState == LS_PICKUP ||
|
||||
laraItem->Animation.ActiveState == LS_PICKUP_FROM_CHEST ||
|
||||
|
@ -344,7 +352,9 @@ void DoPickup(ItemInfo* laraItem)
|
|||
return;
|
||||
}
|
||||
|
||||
PickedUpObject(pickupItem->ObjectNumber);
|
||||
g_Hud.PickupSummary.AddDisplayPickup(pickupItem->ObjectNumber, pickupItem->Pose.Position.ToVector3());
|
||||
|
||||
if (pickupItem->TriggerFlags & (1 << 8))
|
||||
{
|
||||
for (int i = 0; i < g_Level.NumItems; i++)
|
||||
|
@ -1261,6 +1271,7 @@ void SearchObjectControl(short itemNumber)
|
|||
|
||||
if (Objects[item2->ObjectNumber].isPickup)
|
||||
{
|
||||
PickedUpObject(item2->ObjectNumber);
|
||||
g_Hud.PickupSummary.AddDisplayPickup(item2->ObjectNumber, item2->Pose.Position.ToVector3());
|
||||
KillItem(item->ItemFlags[1]);
|
||||
}
|
||||
|
@ -1280,7 +1291,6 @@ void SearchObjectControl(short itemNumber)
|
|||
CollectCarriedItems(item);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (item->Status == ITEM_DEACTIVATED)
|
||||
{
|
||||
|
|
|
@ -45,7 +45,9 @@ using namespace TEN::Entities::TR4;
|
|||
|
||||
namespace Save = TEN::Save;
|
||||
|
||||
const std::string SAVEGAME_PATH = "Save//";
|
||||
constexpr auto SAVEGAME_MAX_SLOT = 99;
|
||||
constexpr auto SAVEGAME_PATH = "Save//";
|
||||
constexpr auto SAVEGAME_FILE_MASK = "savegame.";
|
||||
|
||||
GameStats Statistics;
|
||||
SaveGameHeader SavegameInfos[SAVEGAME_MAX];
|
||||
|
@ -62,21 +64,20 @@ void SaveGame::LoadSavegameInfos()
|
|||
if (!std::filesystem::is_directory(FullSaveDirectory))
|
||||
return;
|
||||
|
||||
// Reset overall savegame count.
|
||||
LastSaveGame = 0;
|
||||
|
||||
// Try loading savegame.
|
||||
for (int i = 0; i < SAVEGAME_MAX; i++)
|
||||
{
|
||||
auto fileName = FullSaveDirectory + "savegame." + std::to_string(i);
|
||||
auto savegamePtr = fopen(fileName.c_str(), "rb");
|
||||
|
||||
if (savegamePtr == nullptr)
|
||||
if (!DoesSaveGameExist(i, true))
|
||||
continue;
|
||||
|
||||
fclose(savegamePtr);
|
||||
|
||||
SavegameInfos[i].Present = true;
|
||||
SaveGame::LoadHeader(i, &SavegameInfos[i]);
|
||||
|
||||
fclose(savegamePtr);
|
||||
if (SavegameInfos[i].Count > LastSaveGame)
|
||||
LastSaveGame = SavegameInfos[i].Count;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -163,6 +164,35 @@ Vector4 ToVector4(const Save::Vector4* vec)
|
|||
return Vector4(vec->x(), vec->y(), vec->z(), vec->w());
|
||||
}
|
||||
|
||||
bool SaveGame::IsSaveGameSlotValid(int slot)
|
||||
{
|
||||
if (slot < 0 || slot > SAVEGAME_MAX_SLOT)
|
||||
{
|
||||
TENLog("Attempted to access invalid savegame slot " + std::to_string(slot), LogLevel::Warning);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SaveGame::DoesSaveGameExist(int slot, bool silent)
|
||||
{
|
||||
if (!std::filesystem::is_regular_file(GetSavegameFilename(slot)))
|
||||
{
|
||||
if (!silent)
|
||||
TENLog("Attempted to access missing savegame slot " + std::to_string(slot), LogLevel::Warning);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string SaveGame::GetSavegameFilename(int slot)
|
||||
{
|
||||
return (FullSaveDirectory + SAVEGAME_FILE_MASK + std::to_string(slot));
|
||||
}
|
||||
|
||||
#define SaveVec(Type, Data, TableBuilder, UnionType, SaveType, ConversionFunc) \
|
||||
auto data = std::get<(int)Type>(Data); \
|
||||
TableBuilder vtb{ fbb }; \
|
||||
|
@ -178,7 +208,15 @@ void SaveGame::Init(const std::string& gameDirectory)
|
|||
|
||||
bool SaveGame::Save(int slot)
|
||||
{
|
||||
auto fileName = FullSaveDirectory + "savegame." + std::to_string(slot);
|
||||
if (!IsSaveGameSlotValid(slot))
|
||||
return false;
|
||||
|
||||
g_GameScript->OnSave();
|
||||
|
||||
// Savegame infos need to be reloaded so that last savegame counter properly increases.
|
||||
SaveGame::LoadSavegameInfos();
|
||||
|
||||
auto fileName = GetSavegameFilename(slot);
|
||||
TENLog("Saving to savegame: " + fileName, LogLevel::Info);
|
||||
|
||||
ItemInfo itemToSerialize{};
|
||||
|
@ -805,9 +843,9 @@ bool SaveGame::Save(int slot)
|
|||
{
|
||||
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);
|
||||
serializedEventSetCallCounter.add_on_enter(set.Events[(int)VolumeEventType::Enter].CallCounter);
|
||||
serializedEventSetCallCounter.add_on_inside(set.Events[(int)VolumeEventType::Inside].CallCounter);
|
||||
serializedEventSetCallCounter.add_on_leave(set.Events[(int)VolumeEventType::Leave].CallCounter);
|
||||
|
||||
auto serializedEventSetCallCounterOffset = serializedEventSetCallCounter.Finish();
|
||||
serializedEventSetCallCounters.push_back(serializedEventSetCallCounterOffset);
|
||||
|
@ -1351,7 +1389,13 @@ bool SaveGame::Save(int slot)
|
|||
|
||||
bool SaveGame::Load(int slot)
|
||||
{
|
||||
auto fileName = FullSaveDirectory + "savegame." + std::to_string(slot);
|
||||
if (!IsSaveGameSlotValid(slot))
|
||||
return false;
|
||||
|
||||
if (!DoesSaveGameExist(slot))
|
||||
return false;
|
||||
|
||||
auto fileName = GetSavegameFilename(slot);
|
||||
TENLog("Loading from savegame: " + fileName, LogLevel::Info);
|
||||
|
||||
std::ifstream file;
|
||||
|
@ -1366,7 +1410,6 @@ bool SaveGame::Load(int slot)
|
|||
const Save::SaveGame* s = Save::GetSaveGame(buffer.get());
|
||||
|
||||
// Statistics
|
||||
LastSaveGame = s->header()->count();
|
||||
GameTimer = s->header()->timer();
|
||||
|
||||
Statistics.Game.AmmoHits = s->game()->ammo_hits();
|
||||
|
@ -1868,9 +1911,9 @@ bool SaveGame::Load(int slot)
|
|||
{
|
||||
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();
|
||||
g_Level.EventSets[i].Events[(int)VolumeEventType::Enter].CallCounter = cc_saved->on_enter();
|
||||
g_Level.EventSets[i].Events[(int)VolumeEventType::Inside].CallCounter = cc_saved->on_inside();
|
||||
g_Level.EventSets[i].Events[(int)VolumeEventType::Leave].CallCounter = cc_saved->on_leave();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2206,7 +2249,13 @@ bool SaveGame::Load(int slot)
|
|||
|
||||
bool SaveGame::LoadHeader(int slot, SaveGameHeader* header)
|
||||
{
|
||||
auto fileName = FullSaveDirectory + "savegame." + std::to_string(slot);
|
||||
if (!IsSaveGameSlotValid(slot))
|
||||
return false;
|
||||
|
||||
if (!DoesSaveGameExist(slot))
|
||||
return false;
|
||||
|
||||
auto fileName = GetSavegameFilename(slot);
|
||||
|
||||
std::ifstream file;
|
||||
file.open(fileName, std::ios_base::app | std::ios_base::binary);
|
||||
|
@ -2231,3 +2280,14 @@ bool SaveGame::LoadHeader(int slot, SaveGameHeader* header)
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SaveGame::Delete(int slot)
|
||||
{
|
||||
if (!IsSaveGameSlotValid(slot))
|
||||
return;
|
||||
|
||||
if (!DoesSaveGameExist(slot))
|
||||
return;
|
||||
|
||||
std::filesystem::remove(GetSavegameFilename(slot));
|
||||
}
|
||||
|
|
|
@ -46,6 +46,9 @@ class SaveGame
|
|||
private:
|
||||
static FileStream* StreamPtr;
|
||||
static std::string FullSaveDirectory;
|
||||
|
||||
static std::string SaveGame::GetSavegameFilename(int slot);
|
||||
static bool IsSaveGameSlotValid(int slot);
|
||||
|
||||
public:
|
||||
static int LastSaveGame;
|
||||
|
@ -55,4 +58,7 @@ public:
|
|||
static bool LoadHeader(int slot, SaveGameHeader* header);
|
||||
static bool Save(int slot);
|
||||
static void LoadSavegameInfos();
|
||||
static void Delete(int slot);
|
||||
|
||||
static bool DoesSaveGameExist(int slot, bool silent = false);
|
||||
};
|
||||
|
|
|
@ -360,9 +360,9 @@ void PuzzleDone(ItemInfo* item, short itemNumber)
|
|||
|
||||
void PuzzleHole(ItemInfo* item, short itemNumber)
|
||||
{
|
||||
// Display pickup object. TODO: Get offset.
|
||||
auto objectID = GAME_OBJECT_ID(item->ObjectNumber - (ID_PUZZLE_DONE1 - ID_PUZZLE_ITEM1));
|
||||
g_Hud.PickupSummary.AddDisplayPickup(objectID, item->Pose.Position.ToVector3());
|
||||
PickedUpObject(objectID);
|
||||
g_Hud.PickupSummary.AddDisplayPickup(objectID, item->Pose.Position.ToVector3()); // TODO: Get appealing position offset.
|
||||
|
||||
item->ItemFlags[1] = true;
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@ namespace TEN::Entities::Creatures::TR2
|
|||
InitializeItem(skidooItemNumber); g_Level.NumItems++;
|
||||
|
||||
// Register snowmobile gun for driver to control.
|
||||
riderItem.Data = skidooItemNumber;
|
||||
riderItem.ItemFlags[0] = skidooItemNumber;
|
||||
}
|
||||
|
||||
void InitializeSkidooMan(short itemNumber)
|
||||
|
@ -118,17 +118,17 @@ namespace TEN::Entities::Creatures::TR2
|
|||
void SkidooManControl(short riderItemNumber)
|
||||
{
|
||||
auto& riderItem = g_Level.Items[riderItemNumber];
|
||||
if (!riderItem.Data)
|
||||
if (!riderItem.ItemFlags[0])
|
||||
{
|
||||
// Create snowmobile.
|
||||
CreateSkidooGun(riderItem);
|
||||
if (!riderItem.Data)
|
||||
if (!riderItem.ItemFlags[0])
|
||||
TENLog("Skidoo rider data does not contain skidoo item ID.", LogLevel::Error);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int skidooItemNumber = (short)riderItem.Data;
|
||||
int skidooItemNumber = (short)riderItem.ItemFlags[0];
|
||||
auto* skidooItem = &g_Level.Items[skidooItemNumber];
|
||||
|
||||
if (!skidooItem->Data)
|
||||
|
|
|
@ -87,7 +87,6 @@ namespace TEN::Traps::TR5
|
|||
{
|
||||
constexpr auto VEL_ACCEL = 5.0f;
|
||||
constexpr auto VEL_MAX = 100.0f;
|
||||
constexpr auto SLOPE_ANGLE = -ANGLE(11.25f);
|
||||
|
||||
auto& zipLineItem = g_Level.Items[itemNumber];
|
||||
auto& laraItem = *LaraItem;
|
||||
|
@ -124,8 +123,10 @@ namespace TEN::Traps::TR5
|
|||
zipLineItem.Animation.Velocity.y += VEL_ACCEL;
|
||||
|
||||
// Translate.
|
||||
auto headingOrient = EulerAngles(SLOPE_ANGLE, zipLineItem.Pose.Orientation.y, 0);
|
||||
// TODO: Use proper calculation of the trajectory instead of bitwise operation.
|
||||
auto headingOrient = EulerAngles(0, zipLineItem.Pose.Orientation.y, 0);
|
||||
TranslateItem(&zipLineItem, headingOrient, zipLineItem.Animation.Velocity.y);
|
||||
zipLineItem.Pose.Position.y += ((int)zipLineItem.Animation.Velocity.y >> 2);
|
||||
|
||||
int vPos = zipLineItem.Pose.Position.y + CLICK(0.25f);
|
||||
auto pointColl = GetCollision(&zipLineItem, zipLineItem.Pose.Orientation.y, zipLineItem.Animation.Velocity.y);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include "framework.h"
|
||||
#include "RenderView.h"
|
||||
#include "Renderer/RenderView/RenderView.h"
|
||||
|
||||
namespace TEN::Renderer
|
||||
{
|
||||
|
@ -46,9 +46,9 @@ namespace TEN::Renderer
|
|||
RoomsToDraw.clear();
|
||||
LightsToDraw.clear();
|
||||
SpritesToDraw.clear();
|
||||
DisplaySpritesToDraw.clear();
|
||||
SortedStaticsToDraw.clear();
|
||||
FogBulbsToDraw.clear();
|
||||
Sprites2DToDraw.clear();
|
||||
}
|
||||
|
||||
RenderViewCamera::RenderViewCamera(CAMERA_INFO* cam, float roll, float fov, float n, float f, int w, int h)
|
||||
|
|
|
@ -1,16 +1,12 @@
|
|||
#pragma once
|
||||
#include <vector>
|
||||
#include <d3d11.h>
|
||||
#include <SimpleMath.h>
|
||||
|
||||
#include "Game/camera.h"
|
||||
#include "Renderer/Frustum.h"
|
||||
#include "Renderer/ConstantBuffers/CameraMatrixBuffer.h"
|
||||
#include "Renderer/Frustum.h"
|
||||
#include "Specific/memory/LinearArrayBuffer.h"
|
||||
#include "Renderer/RendererSprite2D.h"
|
||||
#include "Renderer/RendererSprites.h"
|
||||
#include "Renderer/RendererTransparentFace.h"
|
||||
#include "Renderer/Structures/RendererFogBulb.h"
|
||||
#include "Specific/memory/LinearArrayBuffer.h"
|
||||
#include "Renderer/RendererSprite2D.h"
|
||||
|
||||
namespace TEN::Renderer
|
||||
{
|
||||
|
@ -20,6 +16,7 @@ namespace TEN::Renderer
|
|||
struct RendererEffect;
|
||||
struct RendererRoom;
|
||||
struct RendererTransparentFace;
|
||||
|
||||
constexpr auto MAX_ROOMS_DRAW = 256;
|
||||
constexpr auto MAX_STATICS_DRAW = 128;
|
||||
constexpr auto MAX_EFFECTS_DRAW = 16;
|
||||
|
@ -27,9 +24,6 @@ namespace TEN::Renderer
|
|||
constexpr auto MAX_LIGHTS_DRAW = 48;
|
||||
constexpr auto MAX_FOG_BULBS_DRAW = 32;
|
||||
constexpr auto MAX_SPRITES_DRAW = 512;
|
||||
using DirectX::SimpleMath::Vector3;
|
||||
using DirectX::SimpleMath::Vector2;
|
||||
using DirectX::SimpleMath::Matrix;
|
||||
|
||||
struct RenderViewCamera
|
||||
{
|
||||
|
@ -52,16 +46,18 @@ namespace TEN::Renderer
|
|||
struct RenderView
|
||||
{
|
||||
RenderViewCamera Camera;
|
||||
D3D11_VIEWPORT Viewport;
|
||||
std::vector<RendererRoom*> RoomsToDraw;
|
||||
std::vector<RendererLight*> LightsToDraw;
|
||||
std::vector<RendererFogBulb> FogBulbsToDraw;
|
||||
std::vector<RendererSpriteToDraw> SpritesToDraw;
|
||||
std::vector<RendererSprite2DToDraw> Sprites2DToDraw;
|
||||
std::map<int, std::vector<RendererStatic*>> SortedStaticsToDraw;
|
||||
D3D11_VIEWPORT Viewport;
|
||||
|
||||
std::vector<RendererRoom*> RoomsToDraw = {};
|
||||
std::vector<RendererLight*> LightsToDraw = {};
|
||||
std::vector<RendererFogBulb> FogBulbsToDraw = {};
|
||||
std::vector<RendererSpriteToDraw> SpritesToDraw = {};
|
||||
std::vector<RendererDisplaySpriteToDraw> DisplaySpritesToDraw = {};
|
||||
std::map<int, std::vector<RendererStatic*>> SortedStaticsToDraw = {};
|
||||
|
||||
RenderView(CAMERA_INFO* cam, float roll, float fov, float nearPlane, float farPlane, int w, int h);
|
||||
RenderView(const Vector3& pos, const Vector3& dir, const Vector3& up, int w, int h, int room, float nearPlane, float farPlane, float fov);
|
||||
|
||||
void fillConstantBuffer(CCameraMatrixBuffer& bufferToFill);
|
||||
void clear();
|
||||
};
|
||||
|
|
|
@ -555,7 +555,7 @@ namespace TEN::Renderer
|
|||
void DrawEffect(RenderView& view, RendererEffect* effect, RendererPass rendererPass);
|
||||
void DrawSplashes(RenderView& view);
|
||||
void DrawSprites(RenderView& view);
|
||||
void DrawScreenSprites(RenderView& view);
|
||||
void DrawDisplaySprites(RenderView& view);
|
||||
void DrawSortedFaces(RenderView& view);
|
||||
void DrawLines3D(RenderView& view);
|
||||
void DrawLinesIn2DSpace();
|
||||
|
@ -746,9 +746,9 @@ namespace TEN::Renderer
|
|||
std::optional<Vector2> Get2DPosition(const Vector3& pos) const;
|
||||
Vector3 GetAbsEntityBonePosition(int itemNumber, int jointIndex, const Vector3& relOffset = Vector3::Zero);
|
||||
|
||||
void AddScreenSprite(RendererSprite* spritePtr, const Vector2& pos2D, short orient, const Vector2& size,
|
||||
const Vector4& color, int priority, BLEND_MODES blendMode, RenderView& renderView);
|
||||
void CollectScreenSprites(RenderView& renderView);
|
||||
void AddDisplaySprite(RendererSprite* spritePtr, const Vector2& pos2D, short orient, const Vector2& size, const Vector4& color,
|
||||
int priority, BLEND_MODES blendMode, RenderView& renderView);
|
||||
void CollectDisplaySprites(RenderView& renderView);
|
||||
};
|
||||
|
||||
extern Renderer11 g_Renderer;
|
||||
|
|
|
@ -609,71 +609,70 @@ namespace TEN::Renderer
|
|||
void Renderer11::DrawScarabs(RenderView& view)
|
||||
{
|
||||
if (!Objects[ID_LITTLE_BEETLE].loaded)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RendererMesh* mesh = GetMesh(Objects[ID_LITTLE_BEETLE].meshIndex + ((Wibble >> 2) % 2));
|
||||
auto& mesh = *GetMesh(Objects[ID_LITTLE_BEETLE].meshIndex + ((Wibble >> 2) % 2));
|
||||
|
||||
int littleBeetlesCount = 0;
|
||||
m_context->VSSetShader(m_vsInstancedStaticMeshes.Get(), nullptr, 0);
|
||||
m_context->PSSetShader(m_psInstancedStaticMeshes.Get(), nullptr, 0);
|
||||
|
||||
UINT stride = sizeof(RendererVertex);
|
||||
UINT offset = 0;
|
||||
|
||||
m_context->IASetVertexBuffers(0, 1, m_moveablesVertexBuffer.Buffer.GetAddressOf(), &stride, &offset);
|
||||
m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
m_context->IASetInputLayout(m_inputLayout.Get());
|
||||
m_context->IASetIndexBuffer(m_moveablesIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0);
|
||||
|
||||
SetAlphaTest(ALPHA_TEST_GREATER_THAN, ALPHA_TEST_THRESHOLD);
|
||||
|
||||
BindConstantBufferVS(CB_INSTANCED_STATICS, m_cbInstancedStaticMeshBuffer.get());
|
||||
BindConstantBufferPS(CB_INSTANCED_STATICS, m_cbInstancedStaticMeshBuffer.get());
|
||||
|
||||
int beetleCount = 0;
|
||||
|
||||
for (int i = 0; i < TEN::Entities::TR4::NUM_BEETLES; i++)
|
||||
{
|
||||
auto* beetle = &TEN::Entities::TR4::BeetleSwarm[i];
|
||||
auto& beetle = TEN::Entities::TR4::BeetleSwarm[i];
|
||||
|
||||
if (beetle->On)
|
||||
if (beetle.On)
|
||||
{
|
||||
RendererRoom& room = m_rooms[beetle->RoomNumber];
|
||||
auto& room = m_rooms[beetle.RoomNumber];
|
||||
|
||||
Matrix translation = Matrix::CreateTranslation(beetle->Pose.Position.x, beetle->Pose.Position.y, beetle->Pose.Position.z);
|
||||
Matrix rotation = beetle->Pose.Orientation.ToRotationMatrix();
|
||||
Matrix world = rotation * translation;
|
||||
auto tmatrix = Matrix::CreateTranslation(beetle.Pose.Position.ToVector3());
|
||||
auto rotMatrix = beetle.Pose.Orientation.ToRotationMatrix();
|
||||
auto worldMatrix = rotMatrix * tmatrix;
|
||||
|
||||
m_stInstancedStaticMeshBuffer.StaticMeshes[littleBeetlesCount].World = world;
|
||||
m_stInstancedStaticMeshBuffer.StaticMeshes[littleBeetlesCount].Ambient = room.AmbientLight;
|
||||
m_stInstancedStaticMeshBuffer.StaticMeshes[littleBeetlesCount].Color = Vector4::One;
|
||||
m_stInstancedStaticMeshBuffer.StaticMeshes[littleBeetlesCount].LightMode = mesh->LightMode;
|
||||
BindInstancedStaticLights(room.LightsToDraw, littleBeetlesCount);
|
||||
m_stInstancedStaticMeshBuffer.StaticMeshes[beetleCount].World = worldMatrix;
|
||||
m_stInstancedStaticMeshBuffer.StaticMeshes[beetleCount].Ambient = room.AmbientLight;
|
||||
m_stInstancedStaticMeshBuffer.StaticMeshes[beetleCount].Color = Vector4::One;
|
||||
m_stInstancedStaticMeshBuffer.StaticMeshes[beetleCount].LightMode = mesh.LightMode;
|
||||
BindInstancedStaticLights(room.LightsToDraw, beetleCount);
|
||||
|
||||
littleBeetlesCount++;
|
||||
}
|
||||
}
|
||||
beetleCount++;
|
||||
|
||||
if (littleBeetlesCount > 0)
|
||||
{
|
||||
m_context->VSSetShader(m_vsInstancedStaticMeshes.Get(), nullptr, 0);
|
||||
m_context->PSSetShader(m_psInstancedStaticMeshes.Get(), nullptr, 0);
|
||||
|
||||
UINT stride = sizeof(RendererVertex);
|
||||
UINT offset = 0;
|
||||
|
||||
m_context->IASetVertexBuffers(0, 1, m_moveablesVertexBuffer.Buffer.GetAddressOf(), &stride, &offset);
|
||||
m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
m_context->IASetInputLayout(m_inputLayout.Get());
|
||||
m_context->IASetIndexBuffer(m_moveablesIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0);
|
||||
|
||||
SetAlphaTest(ALPHA_TEST_GREATER_THAN, ALPHA_TEST_THRESHOLD);
|
||||
|
||||
m_cbInstancedStaticMeshBuffer.updateData(m_stInstancedStaticMeshBuffer, m_context.Get());
|
||||
|
||||
BindConstantBufferVS(CB_INSTANCED_STATICS, m_cbInstancedStaticMeshBuffer.get());
|
||||
BindConstantBufferPS(CB_INSTANCED_STATICS, m_cbInstancedStaticMeshBuffer.get());
|
||||
|
||||
for (auto& bucket : mesh->Buckets)
|
||||
{
|
||||
if (bucket.NumVertices == 0 && bucket.BlendMode == BLEND_MODES::BLENDMODE_OPAQUE)
|
||||
// If max bucket size reached or last beetle, draw beetles.
|
||||
if (beetleCount == INSTANCED_STATIC_MESH_BUCKET_SIZE || i == (TEN::Entities::TR4::NUM_BEETLES - 1))
|
||||
{
|
||||
continue;
|
||||
m_cbInstancedStaticMeshBuffer.updateData(m_stInstancedStaticMeshBuffer, m_context.Get());
|
||||
|
||||
for (auto& bucket : mesh.Buckets)
|
||||
{
|
||||
if (bucket.NumVertices == 0 && bucket.BlendMode == BLEND_MODES::BLENDMODE_OPAQUE)
|
||||
continue;
|
||||
|
||||
SetBlendMode(bucket.BlendMode);
|
||||
|
||||
BindTexture(TEXTURE_COLOR_MAP, &std::get<0>(m_moveablesTextures[bucket.Texture]), SAMPLER_ANISOTROPIC_CLAMP);
|
||||
BindTexture(TEXTURE_NORMAL_MAP, &std::get<1>(m_moveablesTextures[bucket.Texture]), SAMPLER_NONE);
|
||||
|
||||
DrawIndexedInstancedTriangles(bucket.NumIndices, beetleCount, bucket.StartIndex, 0);
|
||||
|
||||
m_numStaticsDrawCalls++;
|
||||
}
|
||||
|
||||
beetleCount = 0;
|
||||
}
|
||||
|
||||
SetBlendMode(bucket.BlendMode);
|
||||
|
||||
BindTexture(TEXTURE_COLOR_MAP, &std::get<0>(m_moveablesTextures[bucket.Texture]), SAMPLER_ANISOTROPIC_CLAMP);
|
||||
BindTexture(TEXTURE_NORMAL_MAP, &std::get<1>(m_moveablesTextures[bucket.Texture]), SAMPLER_NONE);
|
||||
|
||||
DrawIndexedInstancedTriangles(bucket.NumIndices, littleBeetlesCount, bucket.StartIndex, 0);
|
||||
|
||||
m_numStaticsDrawCalls++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1545,7 +1544,15 @@ namespace TEN::Renderer
|
|||
DrawSprites(view);
|
||||
DrawLines3D(view);
|
||||
|
||||
// Immediately draw additive and unsorted blended faces, and collect all sorted blend modes faces for later.
|
||||
// Collect all sorted blend modes faces for later.
|
||||
DrawRooms(view, RendererPass::CollectSortedFaces);
|
||||
DrawItems(view, RendererPass::CollectSortedFaces);
|
||||
DrawStatics(view, RendererPass::CollectSortedFaces);
|
||||
|
||||
// Draw all sorted blend mode faces collected in previous steps.
|
||||
DrawSortedFaces(view);
|
||||
|
||||
// Draw immediate transparent faces (i.e. additive)
|
||||
DrawRooms(view, RendererPass::Transparent);
|
||||
DrawItems(view, RendererPass::Transparent);
|
||||
DrawStatics(view, RendererPass::Transparent);
|
||||
|
@ -1554,9 +1561,6 @@ namespace TEN::Renderer
|
|||
DrawGunFlashes(view);
|
||||
DrawBaddyGunflashes(view);
|
||||
|
||||
// Draw all sorted blend mode faces collected in previous steps.
|
||||
DrawSortedFaces(view);
|
||||
|
||||
// Draw post-process effects (cinematic bars, fade, flash, HDR, tone mapping, etc.).
|
||||
DrawPostprocess(target, depthTarget, view);
|
||||
|
||||
|
@ -1566,9 +1570,9 @@ namespace TEN::Renderer
|
|||
// Draw HUD.
|
||||
g_Hud.Draw(*LaraItem);
|
||||
|
||||
// Draw screen sprites sorted by priority.
|
||||
CollectScreenSprites(view);
|
||||
DrawScreenSprites(view);
|
||||
// Draw display sprites sorted by priority.
|
||||
CollectDisplaySprites(view);
|
||||
DrawDisplaySprites(view);
|
||||
|
||||
// Draw binoculars or lasersight.
|
||||
DrawOverlays(view);
|
||||
|
@ -1877,7 +1881,8 @@ namespace TEN::Renderer
|
|||
|
||||
for (auto& bucket : refMesh->Buckets)
|
||||
{
|
||||
if (!((bucket.BlendMode == BLENDMODE_OPAQUE || bucket.BlendMode == BLENDMODE_ALPHATEST) ^ (rendererPass == RendererPass::Transparent)))
|
||||
if (!((bucket.BlendMode == BLENDMODE_OPAQUE || bucket.BlendMode == BLENDMODE_ALPHATEST) ^
|
||||
(rendererPass == RendererPass::Transparent)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -1899,9 +1904,8 @@ namespace TEN::Renderer
|
|||
{
|
||||
SetBlendMode(bucket.BlendMode);
|
||||
SetAlphaTest(
|
||||
bucket.BlendMode == BLENDMODE_ALPHATEST ? ALPHA_TEST_GREATER_THAN : ALPHA_TEST_NONE,
|
||||
ALPHA_TEST_THRESHOLD
|
||||
);
|
||||
(bucket.BlendMode == BLENDMODE_ALPHATEST) ? ALPHA_TEST_GREATER_THAN : ALPHA_TEST_NONE,
|
||||
ALPHA_TEST_THRESHOLD);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1925,7 +1929,7 @@ namespace TEN::Renderer
|
|||
}
|
||||
|
||||
// Collect sorted blend modes faces ordered by room, if transparent pass
|
||||
if (rendererPass == RendererPass::Transparent)
|
||||
if (rendererPass == RendererPass::CollectSortedFaces)
|
||||
{
|
||||
Vector3 cameraPosition = Vector3(Camera.pos.x, Camera.pos.y, Camera.pos.z);
|
||||
|
||||
|
@ -1941,11 +1945,6 @@ namespace TEN::Renderer
|
|||
|
||||
for (auto& bucket : mesh->Buckets)
|
||||
{
|
||||
if (!((bucket.BlendMode == BLENDMODE_OPAQUE || bucket.BlendMode == BLENDMODE_ALPHATEST) ^ (rendererPass == RendererPass::Transparent)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (bucket.NumVertices == 0)
|
||||
{
|
||||
continue;
|
||||
|
@ -1990,19 +1989,19 @@ namespace TEN::Renderer
|
|||
UINT stride = sizeof(RendererVertex);
|
||||
UINT offset = 0;
|
||||
|
||||
// Bind vertex and index buffer
|
||||
// Bind vertex and index buffer.
|
||||
m_context->IASetVertexBuffers(0, 1, m_roomsVertexBuffer.Buffer.GetAddressOf(), &stride, &offset);
|
||||
m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
m_context->IASetInputLayout(m_inputLayout.Get());
|
||||
m_context->IASetIndexBuffer(m_roomsIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0);
|
||||
|
||||
// Bind pixel shaders
|
||||
// Bind pixel shaders.
|
||||
m_context->PSSetShader(m_psRooms.Get(), nullptr, 0);
|
||||
|
||||
BindConstantBufferVS(CB_ROOM, m_cbRoom.get());
|
||||
BindConstantBufferPS(CB_ROOM, m_cbRoom.get());
|
||||
|
||||
// Bind caustics texture
|
||||
// Bind caustics texture.
|
||||
if (!m_sprites.empty())
|
||||
{
|
||||
int nmeshes = -Objects[ID_CAUSTICS_TEXTURES].nmeshes;
|
||||
|
@ -2010,13 +2009,13 @@ namespace TEN::Renderer
|
|||
int causticsFrame = std::min(nmeshes ? meshIndex + ((GlobalCounter) % nmeshes) : meshIndex, (int)m_sprites.size());
|
||||
BindTexture(TEXTURE_CAUSTICS, m_sprites[causticsFrame].Texture, SAMPLER_ANISOTROPIC_CLAMP);
|
||||
|
||||
// Strange packing due to particular HLSL 16 bytes alignment requirements
|
||||
// NOTE: Strange packing due to particular HLSL 16 bytes alignment requirements.
|
||||
RendererSprite* causticsSprite = &m_sprites[causticsFrame];
|
||||
m_stRoom.CausticsStartUV = causticsSprite->UV[0];
|
||||
m_stRoom.CausticsScale = Vector2(causticsSprite->Width / (float)causticsSprite->Texture->Width, causticsSprite->Height / (float)causticsSprite->Texture->Height);
|
||||
}
|
||||
|
||||
// Set shadow map data and bind shadow map texture
|
||||
// Set shadow map data and bind shadow map texture.
|
||||
if (m_shadowLight != nullptr)
|
||||
{
|
||||
memcpy(&m_stShadowMap.Light, m_shadowLight, sizeof(ShaderLight));
|
||||
|
@ -2072,14 +2071,15 @@ namespace TEN::Renderer
|
|||
continue;
|
||||
}
|
||||
|
||||
if (!((bucket.BlendMode == BLENDMODE_OPAQUE || bucket.BlendMode == BLENDMODE_ALPHATEST) ^ (rendererPass == RendererPass::Transparent)))
|
||||
if (!((bucket.BlendMode == BLENDMODE_OPAQUE || bucket.BlendMode == BLENDMODE_ALPHATEST) ^
|
||||
(rendererPass == RendererPass::Transparent || rendererPass == RendererPass::CollectSortedFaces)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (DoesBlendModeRequireSorting(bucket.BlendMode))
|
||||
if (rendererPass == RendererPass::CollectSortedFaces && DoesBlendModeRequireSorting(bucket.BlendMode))
|
||||
{
|
||||
// Collect transparent faces
|
||||
// Collect transparent faces.
|
||||
for (int j = 0; j < bucket.Polygons.size(); j++)
|
||||
{
|
||||
RendererPolygon* p = &bucket.Polygons[j];
|
||||
|
@ -2179,20 +2179,20 @@ namespace TEN::Renderer
|
|||
|
||||
void Renderer11::DrawHorizonAndSky(RenderView& renderView, ID3D11DepthStencilView* depthTarget)
|
||||
{
|
||||
ScriptInterfaceLevel* level = g_GameFlow->GetLevel(CurrentLevel);
|
||||
auto* levelPtr = g_GameFlow->GetLevel(CurrentLevel);
|
||||
|
||||
bool anyOutsideRooms = false;
|
||||
for (int k = 0; k < renderView.RoomsToDraw.size(); k++)
|
||||
{
|
||||
ROOM_INFO* nativeRoom = &g_Level.Rooms[renderView.RoomsToDraw[k]->RoomNumber];
|
||||
if (nativeRoom->flags & ENV_FLAG_OUTSIDE)
|
||||
const auto& nativeRoom = g_Level.Rooms[renderView.RoomsToDraw[k]->RoomNumber];
|
||||
if (nativeRoom.flags & ENV_FLAG_OUTSIDE)
|
||||
{
|
||||
anyOutsideRooms = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!level->Horizon || !anyOutsideRooms)
|
||||
if (!levelPtr->Horizon || !anyOutsideRooms)
|
||||
return;
|
||||
|
||||
if (Lara.Control.Look.OpticRange != 0)
|
||||
|
@ -2202,7 +2202,7 @@ namespace TEN::Renderer
|
|||
UINT offset = 0;
|
||||
|
||||
// Draw sky.
|
||||
Matrix rotation = Matrix::CreateRotationX(PI);
|
||||
auto rotation = Matrix::CreateRotationX(PI);
|
||||
|
||||
m_context->VSSetShader(m_vsSky.Get(), nullptr, 0);
|
||||
m_context->PSSetShader(m_psSky.Get(), nullptr, 0);
|
||||
|
@ -2222,9 +2222,9 @@ namespace TEN::Renderer
|
|||
{
|
||||
auto weather = TEN::Effects::Environment::Weather;
|
||||
|
||||
Matrix translation = Matrix::CreateTranslation(Camera.pos.x + weather.SkyPosition(s) - i * SKY_SIZE,
|
||||
auto translation = Matrix::CreateTranslation(Camera.pos.x + weather.SkyPosition(s) - i * SKY_SIZE,
|
||||
Camera.pos.y - 1536.0f, Camera.pos.z);
|
||||
Matrix world = rotation * translation;
|
||||
auto world = rotation * translation;
|
||||
|
||||
m_stSky.World = (rotation * translation);
|
||||
m_stSky.Color = weather.SkyColor(s);
|
||||
|
@ -2240,7 +2240,7 @@ namespace TEN::Renderer
|
|||
|
||||
m_context->ClearDepthStencilView(depthTarget, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1, 0);
|
||||
|
||||
// Draw horizon
|
||||
// Draw horizon.
|
||||
if (m_moveableObjects[ID_HORIZON].has_value())
|
||||
{
|
||||
m_context->IASetVertexBuffers(0, 1, m_moveablesVertexBuffer.Buffer.GetAddressOf(), &stride, &offset);
|
||||
|
@ -2248,7 +2248,7 @@ namespace TEN::Renderer
|
|||
m_context->IASetInputLayout(m_inputLayout.Get());
|
||||
m_context->IASetIndexBuffer(m_moveablesIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0);
|
||||
|
||||
RendererObject& moveableObj = *m_moveableObjects[ID_HORIZON];
|
||||
auto& moveableObj = *m_moveableObjects[ID_HORIZON];
|
||||
|
||||
m_stSky.World = Matrix::CreateTranslation(Camera.pos.x, Camera.pos.y, Camera.pos.z);
|
||||
m_stSky.Color = Vector4::One;
|
||||
|
@ -2260,9 +2260,9 @@ namespace TEN::Renderer
|
|||
|
||||
for (int k = 0; k < moveableObj.ObjectMeshes.size(); k++)
|
||||
{
|
||||
RendererMesh* mesh = moveableObj.ObjectMeshes[k];
|
||||
auto* meshPtr = moveableObj.ObjectMeshes[k];
|
||||
|
||||
for (auto& bucket : mesh->Buckets)
|
||||
for (auto& bucket : meshPtr->Buckets)
|
||||
{
|
||||
if (bucket.NumVertices == 0)
|
||||
continue;
|
||||
|
@ -2272,11 +2272,11 @@ namespace TEN::Renderer
|
|||
BindTexture(TEXTURE_NORMAL_MAP, &std::get<1>(m_moveablesTextures[bucket.Texture]),
|
||||
SAMPLER_ANISOTROPIC_CLAMP);
|
||||
|
||||
// Always render horizon as alpha-blended surface
|
||||
// Always render horizon as alpha-blended surface.
|
||||
SetBlendMode(bucket.BlendMode == BLEND_MODES::BLENDMODE_ALPHATEST ? BLEND_MODES::BLENDMODE_ALPHABLEND : bucket.BlendMode);
|
||||
SetAlphaTest(ALPHA_TEST_NONE, ALPHA_TEST_THRESHOLD);
|
||||
|
||||
// Draw vertices
|
||||
// Draw vertices.
|
||||
DrawIndexedTriangles(bucket.NumIndices, bucket.StartIndex, 0);
|
||||
|
||||
m_numMoveablesDrawCalls++;
|
||||
|
@ -2284,7 +2284,7 @@ namespace TEN::Renderer
|
|||
}
|
||||
}
|
||||
|
||||
// Clear just the Z-buffer so we can start drawing on top of the horizon
|
||||
// Clear just the Z-buffer to start drawing on top of horizon.
|
||||
m_context->ClearDepthStencilView(depthTarget, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
|
||||
}
|
||||
|
||||
|
@ -2298,19 +2298,18 @@ namespace TEN::Renderer
|
|||
|
||||
void Renderer11::DrawMoveableMesh(RendererItem* itemToDraw, RendererMesh* mesh, RendererRoom* room, int boneIndex, RendererPass rendererPass)
|
||||
{
|
||||
Vector3 cameraPosition = Vector3(Camera.pos.x, Camera.pos.y, Camera.pos.z);
|
||||
auto cameraPos = Camera.pos.ToVector3();
|
||||
|
||||
for (auto& bucket : mesh->Buckets)
|
||||
{
|
||||
if (!((bucket.BlendMode == BLENDMODE_OPAQUE || bucket.BlendMode == BLENDMODE_ALPHATEST) ^ (rendererPass == RendererPass::Transparent)))
|
||||
if (!((bucket.BlendMode == BLENDMODE_OPAQUE || bucket.BlendMode == BLENDMODE_ALPHATEST) ^
|
||||
(rendererPass == RendererPass::Transparent || rendererPass == RendererPass::CollectSortedFaces)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (bucket.NumVertices == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (rendererPass == RendererPass::ShadowMap)
|
||||
{
|
||||
|
@ -2321,21 +2320,21 @@ namespace TEN::Renderer
|
|||
|
||||
m_numMoveablesDrawCalls++;
|
||||
}
|
||||
else if (DoesBlendModeRequireSorting(bucket.BlendMode))
|
||||
else if (rendererPass == RendererPass::CollectSortedFaces && DoesBlendModeRequireSorting(bucket.BlendMode))
|
||||
{
|
||||
// Collect transparent faces
|
||||
for (int j = 0; j < bucket.Polygons.size(); j++)
|
||||
{
|
||||
RendererPolygon* p = &bucket.Polygons[j];
|
||||
auto* polygonPtr = &bucket.Polygons[j];
|
||||
|
||||
// As polygon distance, for moveables, we use the averaged distance
|
||||
Vector3 centre = Vector3::Transform(
|
||||
p->centre, itemToDraw->AnimationTransforms[boneIndex] * itemToDraw->World);
|
||||
int distance = (centre - cameraPosition).Length();
|
||||
// Use averaged distance as polygon distance for moveables.
|
||||
auto centre = Vector3::Transform(
|
||||
polygonPtr->centre, itemToDraw->AnimationTransforms[boneIndex] * itemToDraw->World);
|
||||
int distance = (centre - cameraPos).Length();
|
||||
|
||||
RendererTransparentFace face;
|
||||
face.type = RendererTransparentFaceType::TRANSPARENT_FACE_MOVEABLE;
|
||||
face.info.polygon = p;
|
||||
face.info.polygon = polygonPtr;
|
||||
face.distance = distance;
|
||||
face.info.animated = bucket.Animated;
|
||||
face.info.texture = bucket.Texture;
|
||||
|
@ -2363,8 +2362,7 @@ namespace TEN::Renderer
|
|||
SetBlendMode(bucket.BlendMode);
|
||||
SetAlphaTest(
|
||||
bucket.BlendMode == BLENDMODE_ALPHATEST ? ALPHA_TEST_GREATER_THAN : ALPHA_TEST_NONE,
|
||||
ALPHA_TEST_THRESHOLD
|
||||
);
|
||||
ALPHA_TEST_THRESHOLD);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "Game/camera.h"
|
||||
#include "Game/control/control.h"
|
||||
#include "Game/spotcam.h"
|
||||
#include "Game/effects/DisplaySprite.h"
|
||||
#include "Game/effects/weather.h"
|
||||
#include "Game/Lara/lara.h"
|
||||
#include "Game/Setup.h"
|
||||
|
@ -11,9 +12,8 @@
|
|||
#include "Objects/game_object_ids.h"
|
||||
#include "Objects/Utils/object_helper.h"
|
||||
#include "Specific/trutils.h"
|
||||
#include "Game/effects/ScreenSprite.h"
|
||||
|
||||
using namespace TEN::Effects::ScreenSprite;
|
||||
using namespace TEN::Effects::DisplaySprite;
|
||||
using namespace TEN::Effects::Environment;
|
||||
using namespace TEN::Math;
|
||||
|
||||
|
@ -381,11 +381,11 @@ namespace TEN::Renderer
|
|||
DrawFullScreenQuad(texture, Vector3(fade), true);
|
||||
}
|
||||
|
||||
void Renderer11::DrawScreenSprites(RenderView& renderView)
|
||||
void Renderer11::DrawDisplaySprites(RenderView& renderView)
|
||||
{
|
||||
constexpr auto VERTEX_COUNT = 4;
|
||||
|
||||
if (renderView.Sprites2DToDraw.empty())
|
||||
if (renderView.DisplaySpritesToDraw.empty())
|
||||
return;
|
||||
|
||||
m_context->VSSetShader(m_vsFullScreenQuad.Get(), nullptr, 0);
|
||||
|
@ -394,23 +394,19 @@ namespace TEN::Renderer
|
|||
m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
m_context->IASetInputLayout(m_inputLayout.Get());
|
||||
|
||||
RendererSprite* currentSpritePtr = nullptr;
|
||||
Texture2D* currentTexturePtr = nullptr;
|
||||
|
||||
for (const auto& spriteToDraw : renderView.Sprites2DToDraw)
|
||||
Texture2D* texture2DPtr = nullptr;
|
||||
for (const auto& spriteToDraw : renderView.DisplaySpritesToDraw)
|
||||
{
|
||||
if (currentTexturePtr == nullptr)
|
||||
if (texture2DPtr == nullptr)
|
||||
{
|
||||
m_primitiveBatch->Begin();
|
||||
|
||||
BindTexture(TEXTURE_COLOR_MAP, spriteToDraw.SpritePtr->Texture, SAMPLER_ANISOTROPIC_CLAMP);
|
||||
SetBlendMode(spriteToDraw.BlendMode);
|
||||
}
|
||||
else if (currentTexturePtr != spriteToDraw.SpritePtr->Texture ||
|
||||
lastBlendMode != spriteToDraw.BlendMode)
|
||||
else if (texture2DPtr != spriteToDraw.SpritePtr->Texture || lastBlendMode != spriteToDraw.BlendMode)
|
||||
{
|
||||
m_primitiveBatch->End();
|
||||
|
||||
m_primitiveBatch->Begin();
|
||||
|
||||
BindTexture(TEXTURE_COLOR_MAP, spriteToDraw.SpritePtr->Texture, SAMPLER_ANISOTROPIC_CLAMP);
|
||||
|
@ -418,16 +414,16 @@ namespace TEN::Renderer
|
|||
}
|
||||
|
||||
// Calculate vertex base.
|
||||
auto halfSize = spriteToDraw.Size / 2;
|
||||
auto vertices = std::array<Vector2, VERTEX_COUNT>
|
||||
{
|
||||
halfSize,
|
||||
Vector2(-halfSize.x, halfSize.y),
|
||||
-halfSize,
|
||||
Vector2(halfSize.x, -halfSize.y)
|
||||
spriteToDraw.Size,
|
||||
Vector2(-spriteToDraw.Size.x, spriteToDraw.Size.y),
|
||||
-spriteToDraw.Size,
|
||||
Vector2(spriteToDraw.Size.x, -spriteToDraw.Size.y)
|
||||
};
|
||||
|
||||
// Transform vertices. // NOTE: Must rotate 180 degrees to account for +Y being down.
|
||||
// Transform vertices.
|
||||
// NOTE: Must rotate 180 degrees to account for +Y being down.
|
||||
auto rotMatrix = Matrix::CreateRotationZ(TO_RAD(spriteToDraw.Orientation + ANGLE(180.0f)));
|
||||
for (auto& vertex : vertices)
|
||||
{
|
||||
|
@ -451,7 +447,7 @@ namespace TEN::Renderer
|
|||
|
||||
m_primitiveBatch->DrawQuad(rVertices[0], rVertices[1], rVertices[2], rVertices[3]);
|
||||
|
||||
currentTexturePtr = spriteToDraw.SpritePtr->Texture;
|
||||
texture2DPtr = spriteToDraw.SpritePtr->Texture;
|
||||
}
|
||||
|
||||
m_primitiveBatch->End();
|
||||
|
@ -467,11 +463,11 @@ namespace TEN::Renderer
|
|||
|
||||
if (fit)
|
||||
{
|
||||
ID3D11Texture2D* texture2D;
|
||||
texture->GetResource(reinterpret_cast<ID3D11Resource**>(&texture2D));
|
||||
ID3D11Texture2D* texture2DPtr;
|
||||
texture->GetResource(reinterpret_cast<ID3D11Resource**>(&texture2DPtr));
|
||||
|
||||
auto desc = D3D11_TEXTURE2D_DESC();
|
||||
texture2D->GetDesc(&desc);
|
||||
texture2DPtr->GetDesc(&desc);
|
||||
|
||||
float screenAspect = float(m_screenWidth) / float(m_screenHeight);
|
||||
float imageAspect = float(desc.Width) / float(desc.Height);
|
||||
|
@ -555,7 +551,7 @@ namespace TEN::Renderer
|
|||
}
|
||||
}
|
||||
|
||||
Vector2 scale = Vector2(sprite->Width / (float)sprite->Texture->Width, sprite->Height / (float)sprite->Texture->Height);
|
||||
auto scale = Vector2(sprite->Width / (float)sprite->Texture->Width, sprite->Height / (float)sprite->Texture->Height);
|
||||
uvStart.x = uvStart.x * scale.x + sprite->UV[0].x;
|
||||
uvStart.y = uvStart.y * scale.y + sprite->UV[0].y;
|
||||
uvEnd.x = uvEnd.x * scale.x + sprite->UV[0].x;
|
||||
|
@ -595,7 +591,7 @@ namespace TEN::Renderer
|
|||
m_context->PSSetShader(m_psFullScreenQuad.Get(), nullptr, 0);
|
||||
|
||||
m_context->PSSetShaderResources(0, 1, &texture);
|
||||
ID3D11SamplerState* sampler = m_states->AnisotropicClamp();
|
||||
auto* sampler = m_states->AnisotropicClamp();
|
||||
m_context->PSSetSamplers(0, 1, &sampler);
|
||||
|
||||
m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
|
@ -606,10 +602,10 @@ namespace TEN::Renderer
|
|||
m_primitiveBatch->End();
|
||||
}
|
||||
|
||||
void Renderer11::AddScreenSprite(RendererSprite* spritePtr, const Vector2& pos2D, short orient, const Vector2& size,
|
||||
const Vector4& color, int priority, BLEND_MODES blendMode, RenderView& renderView)
|
||||
void Renderer11::AddDisplaySprite(RendererSprite* spritePtr, const Vector2& pos2D, short orient, const Vector2& size, const Vector4& color,
|
||||
int priority, BLEND_MODES blendMode, RenderView& renderView)
|
||||
{
|
||||
auto spriteToDraw = RendererSprite2DToDraw{};
|
||||
auto spriteToDraw = RendererDisplaySpriteToDraw{};
|
||||
|
||||
spriteToDraw.SpritePtr = spritePtr;
|
||||
spriteToDraw.Position = pos2D;
|
||||
|
@ -619,33 +615,123 @@ namespace TEN::Renderer
|
|||
spriteToDraw.Priority = priority;
|
||||
spriteToDraw.BlendMode = blendMode;
|
||||
|
||||
renderView.Sprites2DToDraw.push_back(spriteToDraw);
|
||||
renderView.DisplaySpritesToDraw.push_back(spriteToDraw);
|
||||
}
|
||||
|
||||
void Renderer11::CollectScreenSprites(RenderView& renderView)
|
||||
void Renderer11::CollectDisplaySprites(RenderView& renderView)
|
||||
{
|
||||
for (const auto& screenSprite : ScreenSprites)
|
||||
// Get screen resolution, dimensions, and aspect ratio.
|
||||
auto screenRes = GetScreenResolution().ToVector2();
|
||||
float screenAspect = screenRes.x / screenRes.y;
|
||||
float screenWidthMax = (SCREEN_SPACE_RES.x / screenRes.x) * screenRes.x;
|
||||
float screenHeightMax = (SCREEN_SPACE_RES.y / screenRes.y) * screenRes.y;
|
||||
|
||||
for (const auto& displaySprite : DisplaySprites)
|
||||
{
|
||||
AddScreenSprite(
|
||||
&m_sprites[Objects[screenSprite.ObjectID].meshIndex + screenSprite.SpriteIndex],
|
||||
screenSprite.Position,
|
||||
screenSprite.Orientation,
|
||||
screenSprite.Size,
|
||||
screenSprite.Color,
|
||||
screenSprite.Priority,
|
||||
screenSprite.BlendMode,
|
||||
auto& texture = m_sprites[Objects[displaySprite.ObjectID].meshIndex + displaySprite.SpriteID];
|
||||
|
||||
// Calculate sprite aspect ratio.
|
||||
float spriteAspect = (float)texture.Width / (float)texture.Height;
|
||||
|
||||
// Calculate size.
|
||||
auto halfSize = Vector2::Zero;
|
||||
switch (displaySprite.ScaleMode)
|
||||
{
|
||||
default:
|
||||
case DisplaySpriteScaleMode::Fit:
|
||||
if (screenAspect >= spriteAspect)
|
||||
{
|
||||
halfSize = (Vector2(screenHeightMax) * displaySprite.Scale) / 2;
|
||||
halfSize.x *= spriteAspect;
|
||||
}
|
||||
else
|
||||
{
|
||||
halfSize = (Vector2(screenWidthMax) * displaySprite.Scale) / 2;
|
||||
halfSize.y /= spriteAspect;
|
||||
}
|
||||
break;
|
||||
|
||||
case DisplaySpriteScaleMode::Fill:
|
||||
if (screenAspect >= spriteAspect)
|
||||
{
|
||||
halfSize = (Vector2(screenWidthMax) * displaySprite.Scale) / 2;
|
||||
halfSize.y /= spriteAspect;
|
||||
}
|
||||
else
|
||||
{
|
||||
halfSize = (Vector2(screenHeightMax) * displaySprite.Scale) / 2;
|
||||
halfSize.x *= spriteAspect;
|
||||
}
|
||||
break;
|
||||
|
||||
case DisplaySpriteScaleMode::Stretch:
|
||||
halfSize = Vector2(screenWidthMax, screenHeightMax) * displaySprite.Scale / 2;
|
||||
break;
|
||||
}
|
||||
|
||||
// Calculate position offset.
|
||||
auto offset = Vector2::Zero;
|
||||
switch (displaySprite.AlignMode)
|
||||
{
|
||||
default:
|
||||
case DisplaySpriteAlignMode::Center:
|
||||
break;
|
||||
|
||||
case DisplaySpriteAlignMode::CenterTop:
|
||||
offset = Vector2(0.0f, -halfSize.y);
|
||||
break;
|
||||
|
||||
case DisplaySpriteAlignMode::CenterBottom:
|
||||
offset = Vector2(0.0f, halfSize.y);
|
||||
break;
|
||||
|
||||
case DisplaySpriteAlignMode::CenterLeft:
|
||||
offset = Vector2(-halfSize.x, 0.0f);
|
||||
break;
|
||||
|
||||
case DisplaySpriteAlignMode::CenterRight:
|
||||
offset = Vector2(halfSize.x, 0.0f);
|
||||
break;
|
||||
|
||||
case DisplaySpriteAlignMode::TopLeft:
|
||||
offset = Vector2(-halfSize.x, -halfSize.y);
|
||||
break;
|
||||
|
||||
case DisplaySpriteAlignMode::TopRight:
|
||||
offset = Vector2(halfSize.x, -halfSize.y);
|
||||
break;
|
||||
|
||||
case DisplaySpriteAlignMode::BottomLeft:
|
||||
offset = Vector2(-halfSize.x, halfSize.y);
|
||||
break;
|
||||
|
||||
case DisplaySpriteAlignMode::BottomRight:
|
||||
offset = Vector2(halfSize.x, halfSize.y);
|
||||
break;
|
||||
}
|
||||
//offset = TEN::Utils::GetAspectCorrect2DPosition(offset); // TODO: Check if aspect correction is necessary.
|
||||
|
||||
AddDisplaySprite(
|
||||
&texture,
|
||||
displaySprite.Position + offset,
|
||||
displaySprite.Orientation,
|
||||
halfSize,
|
||||
displaySprite.Color,
|
||||
displaySprite.Priority,
|
||||
displaySprite.BlendMode,
|
||||
renderView);
|
||||
}
|
||||
|
||||
std::sort(
|
||||
renderView.Sprites2DToDraw.begin(), renderView.Sprites2DToDraw.end(),
|
||||
[](const RendererSprite2DToDraw& spriteToDraw0, const RendererSprite2DToDraw& spriteToDraw1)
|
||||
renderView.DisplaySpritesToDraw.begin(), renderView.DisplaySpritesToDraw.end(),
|
||||
[](const RendererDisplaySpriteToDraw& spriteToDraw0, const RendererDisplaySpriteToDraw& spriteToDraw1)
|
||||
{
|
||||
// Same priority; sort by blend mode.
|
||||
if (spriteToDraw0.Priority == spriteToDraw1.Priority)
|
||||
return (spriteToDraw0.BlendMode < spriteToDraw1.BlendMode);
|
||||
|
||||
// Sort by priority.
|
||||
return (spriteToDraw0.Priority < spriteToDraw1.Priority);
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,8 +28,8 @@
|
|||
#include "Math/Math.h"
|
||||
#include "Objects/TR5/Trap/LaserBarrier.h"
|
||||
#include "Objects/Utils/object_helper.h"
|
||||
#include "Renderer/RendererSprites.h"
|
||||
#include "Renderer/RendererSprite2D.h"
|
||||
#include "Renderer/RendererSprites.h"
|
||||
#include "Renderer/Quad/RenderQuad.h"
|
||||
#include "Specific/level.h"
|
||||
|
||||
|
@ -1420,15 +1420,18 @@ namespace TEN::Renderer
|
|||
}
|
||||
|
||||
auto* meshPtr = effect->Mesh;
|
||||
BLEND_MODES lastBlendMode = BLEND_MODES::BLENDMODE_UNSET;
|
||||
auto lastBlendMode = BLEND_MODES::BLENDMODE_UNSET;
|
||||
|
||||
for (auto& bucket : meshPtr->Buckets)
|
||||
{
|
||||
if (bucket.NumVertices == 0)
|
||||
continue;
|
||||
|
||||
if (!((bucket.BlendMode == BLENDMODE_OPAQUE || bucket.BlendMode == BLENDMODE_ALPHATEST) ^ (rendererPass == RendererPass::Transparent)))
|
||||
if (!((bucket.BlendMode == BLENDMODE_OPAQUE || bucket.BlendMode == BLENDMODE_ALPHATEST) ^
|
||||
(rendererPass == RendererPass::Transparent)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
BindTexture(TEXTURE_COLOR_MAP, &std::get<0>(m_moveablesTextures[bucket.Texture]), SAMPLER_ANISOTROPIC_CLAMP);
|
||||
BindTexture(TEXTURE_NORMAL_MAP, &std::get<1>(m_moveablesTextures[bucket.Texture]), SAMPLER_ANISOTROPIC_CLAMP);
|
||||
|
@ -1479,18 +1482,21 @@ namespace TEN::Renderer
|
|||
extern std::vector<DebrisFragment> DebrisFragments;
|
||||
std::vector<RendererVertex> vertices;
|
||||
|
||||
BLEND_MODES lastBlendMode = BLEND_MODES::BLENDMODE_UNSET;
|
||||
auto lastBlendMode = BLEND_MODES::BLENDMODE_UNSET;
|
||||
|
||||
for (auto deb = DebrisFragments.begin(); deb != DebrisFragments.end(); deb++)
|
||||
{
|
||||
if (deb->active)
|
||||
{
|
||||
if (!((deb->mesh.blendMode == BLENDMODE_OPAQUE || deb->mesh.blendMode == BLENDMODE_ALPHATEST) ^ (rendererPass == RendererPass::Transparent)))
|
||||
if (!((deb->mesh.blendMode == BLENDMODE_OPAQUE || deb->mesh.blendMode == BLENDMODE_ALPHATEST) ^
|
||||
(rendererPass == RendererPass::Transparent)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Matrix translation = Matrix::CreateTranslation(deb->worldPosition.x, deb->worldPosition.y, deb->worldPosition.z);
|
||||
Matrix rotation = Matrix::CreateFromQuaternion(deb->rotation);
|
||||
Matrix world = rotation * translation;
|
||||
auto translation = Matrix::CreateTranslation(deb->worldPosition.x, deb->worldPosition.y, deb->worldPosition.z);
|
||||
auto rotation = Matrix::CreateFromQuaternion(deb->rotation);
|
||||
auto world = rotation * translation;
|
||||
|
||||
m_primitiveBatch->Begin();
|
||||
|
||||
|
|
|
@ -461,30 +461,33 @@ namespace TEN::Renderer
|
|||
void Renderer11::RenderTitleMenu(Menu menu)
|
||||
{
|
||||
int y = MenuVerticalBottomCenter;
|
||||
auto titleOption = g_Gui.GetSelectedOption();
|
||||
|
||||
// HACK: Check if it works properly -- Lwmte, 07.06.22
|
||||
if (menu == Menu::LoadGame && !g_GameFlow->EnableLoadSave)
|
||||
menu = Menu::Title;
|
||||
int titleOption = g_Gui.GetSelectedOption();
|
||||
int selectedOption = 0;
|
||||
|
||||
switch (menu)
|
||||
{
|
||||
case Menu::Title:
|
||||
|
||||
// New game
|
||||
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_NEW_GAME), PRINTSTRING_COLOR_WHITE, SF_Center(titleOption == 0));
|
||||
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_NEW_GAME), PRINTSTRING_COLOR_WHITE, SF_Center(titleOption == selectedOption));
|
||||
GetNextLinePosition(&y);
|
||||
selectedOption++;
|
||||
|
||||
// Load game
|
||||
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_LOAD_GAME), PRINTSTRING_COLOR_WHITE, SF_Center(titleOption == 1));
|
||||
GetNextLinePosition(&y);
|
||||
if (g_GameFlow->IsLoadSaveEnabled())
|
||||
{
|
||||
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_LOAD_GAME), PRINTSTRING_COLOR_WHITE, SF_Center(titleOption == selectedOption));
|
||||
GetNextLinePosition(&y);
|
||||
selectedOption++;
|
||||
}
|
||||
|
||||
// Options
|
||||
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_OPTIONS), PRINTSTRING_COLOR_WHITE, SF_Center(titleOption == 2));
|
||||
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_OPTIONS), PRINTSTRING_COLOR_WHITE, SF_Center(titleOption == selectedOption));
|
||||
GetNextLinePosition(&y);
|
||||
selectedOption++;
|
||||
|
||||
// Exit game
|
||||
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_EXIT_GAME), PRINTSTRING_COLOR_WHITE, SF_Center(titleOption == 3));
|
||||
AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_EXIT_GAME), PRINTSTRING_COLOR_WHITE, SF_Center(titleOption == selectedOption));
|
||||
break;
|
||||
|
||||
case Menu::LoadGame:
|
||||
|
@ -501,10 +504,10 @@ namespace TEN::Renderer
|
|||
GetNextBlockPosition(&y);
|
||||
|
||||
// Level listing (starts with 1 because 0 is always title)
|
||||
for (int i = 1; i < g_GameFlow->GetNumLevels(); i++)
|
||||
for (int i = 1; i < g_GameFlow->GetNumLevels(); i++, selectedOption++)
|
||||
{
|
||||
AddString(MenuCenterEntry, y, g_GameFlow->GetString(g_GameFlow->GetLevel(i)->NameStringKey.c_str()),
|
||||
PRINTSTRING_COLOR_WHITE, SF_Center(titleOption == i - 1));
|
||||
PRINTSTRING_COLOR_WHITE, SF_Center(titleOption == selectedOption));
|
||||
GetNextNarrowLinePosition(&y);
|
||||
}
|
||||
break;
|
||||
|
@ -570,7 +573,7 @@ namespace TEN::Renderer
|
|||
|
||||
void Renderer11::RenderLoadSaveMenu()
|
||||
{
|
||||
if (!g_GameFlow->EnableLoadSave)
|
||||
if (!g_GameFlow->IsLoadSaveEnabled())
|
||||
{
|
||||
g_Gui.SetInventoryMode(InventoryMode::InGame);
|
||||
return;
|
||||
|
@ -580,7 +583,6 @@ namespace TEN::Renderer
|
|||
int y = MenuVerticalLineSpacing;
|
||||
short selection = g_Gui.GetLoadSaveSelection();
|
||||
char stringBuffer[255];
|
||||
SaveGame::LoadSavegameInfos();
|
||||
|
||||
// Title
|
||||
AddString(MenuCenterEntry, MenuVerticalNarrowLineSpacing, Str_LoadSave(g_Gui.GetInventoryMode() == InventoryMode::Save),
|
||||
|
@ -693,7 +695,8 @@ namespace TEN::Renderer
|
|||
|
||||
void Renderer11::DrawDisplayPickup(const DisplayPickup& pickup)
|
||||
{
|
||||
static const auto COUNT_STRING_PREFIX = std::string(" ");
|
||||
constexpr auto COUNT_STRING_INF = "Inf";
|
||||
constexpr auto COUNT_STRING_OFFSET = Vector2(SCREEN_SPACE_RES.x / 40, 0.0f);
|
||||
|
||||
// Clear only Z-buffer to draw on top of the scene.
|
||||
ID3D11DepthStencilView* dsv;
|
||||
|
@ -704,11 +707,12 @@ namespace TEN::Renderer
|
|||
DrawObjectIn2DSpace(pickup.ObjectID, pickup.Position, pickup.Orientation, pickup.Scale);
|
||||
|
||||
// Draw count string.
|
||||
if (pickup.Count > 1)
|
||||
if (pickup.Count != 1)
|
||||
{
|
||||
AddString(
|
||||
COUNT_STRING_PREFIX + std::to_string(pickup.Count),
|
||||
pickup.Position, Color(PRINTSTRING_COLOR_WHITE), pickup.StringScale, SF());
|
||||
auto countString = (pickup.Count != -1) ? std::to_string(pickup.Count) : COUNT_STRING_INF;
|
||||
auto countStringPos = pickup.Position + COUNT_STRING_OFFSET;
|
||||
|
||||
AddString(countString, countStringPos, Color(PRINTSTRING_COLOR_WHITE), pickup.StringScale, SF());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -42,6 +42,8 @@ enum LIGHT_TYPES
|
|||
|
||||
enum BLEND_MODES
|
||||
{
|
||||
BLENDMODE_UNSET = -1,
|
||||
|
||||
BLENDMODE_OPAQUE = 0,
|
||||
BLENDMODE_ALPHATEST = 1,
|
||||
BLENDMODE_ADDITIVE = 2,
|
||||
|
@ -51,8 +53,7 @@ enum BLEND_MODES
|
|||
BLENDMODE_EXCLUDE = 8,
|
||||
BLENDMODE_SCREEN = 9,
|
||||
BLENDMODE_LIGHTEN = 10,
|
||||
BLENDMODE_ALPHABLEND = 11,
|
||||
BLENDMODE_UNSET = -1
|
||||
BLENDMODE_ALPHABLEND = 11
|
||||
};
|
||||
|
||||
enum CULL_MODES
|
||||
|
@ -193,11 +194,20 @@ enum ALPHA_TEST_MODES
|
|||
ALPHA_TEST_LESS_THAN = 2
|
||||
};
|
||||
|
||||
enum PrintStringFlags
|
||||
{
|
||||
PRINTSTRING_CENTER = (1 << 0),
|
||||
PRINTSTRING_BLINK = (1 << 1),
|
||||
PRINTSTRING_RIGHT = (1 << 2),
|
||||
PRINTSTRING_OUTLINE = (1 << 3)
|
||||
};
|
||||
|
||||
enum RendererPass
|
||||
{
|
||||
ShadowMap,
|
||||
Opaque,
|
||||
Transparent
|
||||
Transparent,
|
||||
CollectSortedFaces
|
||||
};
|
||||
|
||||
constexpr auto TEXTURE_HEIGHT = 256;
|
||||
|
@ -222,9 +232,6 @@ constexpr auto TEXTURE_PAGE = (TEXTURE_HEIGHT * TEXTURE_WIDTH);
|
|||
#define NUM_SPRITES_PER_BUCKET 4096
|
||||
#define NUM_LINES_PER_BUCKET 4096
|
||||
#define NUM_CAUSTICS_TEXTURES 16
|
||||
#define PRINTSTRING_CENTER 1
|
||||
#define PRINTSTRING_BLINK 2
|
||||
#define PRINTSTRING_OUTLINE 8
|
||||
#define PRINTSTRING_COLOR_ORANGE D3DCOLOR_ARGB(255, 216, 117, 49)
|
||||
#define PRINTSTRING_COLOR_WHITE D3DCOLOR_ARGB(255, 255, 255, 255)
|
||||
#define PRINTSTRING_COLOR_BLACK D3DCOLOR_ARGB(255, 0, 0, 0)
|
||||
|
|
|
@ -296,7 +296,7 @@ namespace TEN::Renderer
|
|||
m_dotProducts++;
|
||||
}
|
||||
|
||||
if (door->DotProduct <= 0)
|
||||
if (door->DotProduct < 0)
|
||||
{
|
||||
door->InvisibleFromCamera = true;
|
||||
continue;
|
||||
|
|
|
@ -55,8 +55,19 @@ namespace TEN::Renderer
|
|||
|
||||
// Measure string.
|
||||
auto size = Vector2(m_gameFont->MeasureString(rString.String.c_str())) * rString.Scale;
|
||||
if (flags & PRINTSTRING_CENTER)
|
||||
{
|
||||
rString.X = (pos.x * factor.x) - (size.x / 2.0f);
|
||||
}
|
||||
else if (flags & PRINTSTRING_RIGHT)
|
||||
{
|
||||
rString.X = (pos.x * factor.x) - size.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
rString.X = pos.x * factor.x;
|
||||
}
|
||||
|
||||
rString.X = (flags & PRINTSTRING_CENTER) ? ((pos.x * factor.x) - (size.x / 2.0f)) : (pos.x * factor.x);
|
||||
rString.Y = (pos.y * uiScale) + yOffset;
|
||||
|
||||
if (flags & PRINTSTRING_BLINK)
|
||||
|
|
|
@ -5,7 +5,7 @@ namespace TEN::Renderer
|
|||
{
|
||||
struct RendererSprite;
|
||||
|
||||
struct RendererSprite2DToDraw
|
||||
struct RendererDisplaySpriteToDraw
|
||||
{
|
||||
RendererSprite* SpritePtr = nullptr;
|
||||
|
||||
|
@ -14,7 +14,7 @@ namespace TEN::Renderer
|
|||
Vector2 Size = Vector2::Zero;
|
||||
Vector4 Color = Vector4::Zero;
|
||||
|
||||
int Priority = 0;
|
||||
BLEND_MODES BlendMode = BLENDMODE_ALPHABLEND;
|
||||
int Priority = 0;
|
||||
BLEND_MODES BlendMode = BLENDMODE_ALPHABLEND;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,23 +1,24 @@
|
|||
#pragma once
|
||||
|
||||
enum class TITLE_TYPE
|
||||
{
|
||||
FLYBY,
|
||||
BACKGROUND
|
||||
};
|
||||
|
||||
class ScriptInterfaceLevel;
|
||||
|
||||
enum class TitleType
|
||||
{
|
||||
Flyby,
|
||||
Background
|
||||
};
|
||||
|
||||
class ScriptInterfaceFlowHandler
|
||||
{
|
||||
public:
|
||||
std::string IntroImagePath{};
|
||||
int SelectedLevelForNewGame{ 0 };
|
||||
int SelectedSaveGame{ 0 };
|
||||
bool EnableLoadSave{ true };
|
||||
int TotalNumberOfSecrets{ 0 };
|
||||
std::string TitleScreenImagePath{};
|
||||
TITLE_TYPE TitleType{ TITLE_TYPE::FLYBY };
|
||||
TitleType TitleType = TitleType::Flyby;
|
||||
std::string IntroImagePath = {};
|
||||
std::string TitleScreenImagePath = {};
|
||||
|
||||
int SelectedLevelForNewGame = 0;
|
||||
int SelectedSaveGame = 0;
|
||||
|
||||
int TotalNumberOfSecrets = 0;
|
||||
|
||||
virtual ~ScriptInterfaceFlowHandler() = default;
|
||||
|
||||
|
@ -32,6 +33,7 @@ public:
|
|||
virtual bool IsMassPickupEnabled() const = 0;
|
||||
virtual bool IsPointFilterEnabled() const = 0;
|
||||
virtual bool IsLaraInTitleEnabled() const = 0;
|
||||
virtual bool IsLoadSaveEnabled() const = 0;
|
||||
virtual bool HasCrawlExtended() const = 0;
|
||||
virtual bool HasCrouchRoll() const = 0;
|
||||
virtual bool HasCrawlspaceDive() const = 0;
|
||||
|
|
|
@ -168,3 +168,4 @@
|
|||
#define STRING_MECHANICAL_SCARAB_1 "mechanical_scarab_1"
|
||||
#define STRING_MECHANICAL_SCARAB_2 "mechanical_scarab_2"
|
||||
#define STRING_VEHICLE_ACTIONS "vehicle_actions"
|
||||
#define STRING_UNLIMITED "unlimited"
|
||||
|
|
|
@ -26,6 +26,12 @@ static constexpr char ScriptReserved_Vec3[] = "Vec3";
|
|||
static constexpr char ScriptReserved_Rotation[] = "Rotation";
|
||||
static constexpr char ScriptReserved_LevelFunc[] = "LevelFunc";
|
||||
|
||||
// DisplaySprite object
|
||||
static constexpr char ScriptReserved_DisplaySprite[] = "DisplaySprite";
|
||||
static constexpr char ScriptReserved_DisplaySpriteDraw[] = "Draw";
|
||||
static constexpr char ScriptReserved_DisplaySpriteTableAlignMode[] = "AlignMode";
|
||||
static constexpr char ScriptReserved_DisplaySpriteTableScaleMode[] = "ScaleMode";
|
||||
|
||||
// Built-in LevelFuncs
|
||||
static constexpr char ScriptReserved_OnStart[] = "OnStart";
|
||||
static constexpr char ScriptReserved_OnLoad[] = "OnLoad";
|
||||
|
@ -51,6 +57,11 @@ static constexpr char ScriptReserved_PostLoad[] = "POSTLOAD";
|
|||
static constexpr char ScriptReserved_PreControlPhase[] = "PRECONTROLPHASE";
|
||||
static constexpr char ScriptReserved_PostControlPhase[] = "POSTCONTROLPHASE";
|
||||
|
||||
// Event types
|
||||
static constexpr char ScriptReserved_OnEnter[] = "ENTER";
|
||||
static constexpr char ScriptReserved_OnInside[] = "INSIDE";
|
||||
static constexpr char ScriptReserved_OnLeave[] = "LEAVE";
|
||||
|
||||
// Member functions
|
||||
static constexpr char ScriptReserved_New[] = "New";
|
||||
static constexpr char ScriptReserved_Init[] = "Init";
|
||||
|
@ -168,6 +179,10 @@ static constexpr char ScriptReserved_SetFarView[] = "SetFarView";
|
|||
static constexpr char ScriptReserved_SetSettings[] = "SetSettings";
|
||||
static constexpr char ScriptReserved_SetAnimations[] = "SetAnimations";
|
||||
static constexpr char ScriptReserved_EndLevel[] = "EndLevel";
|
||||
static constexpr char ScriptReserved_SaveGame[] = "SaveGame";
|
||||
static constexpr char ScriptReserved_LoadGame[] = "LoadGame";
|
||||
static constexpr char ScriptReserved_DeleteSaveGame[] = "DeleteSaveGame";
|
||||
static constexpr char ScriptReserved_DoesSaveGameExist[] = "DoesSaveGameExist";
|
||||
static constexpr char ScriptReserved_GetSecretCount[] = "GetSecretCount";
|
||||
static constexpr char ScriptReserved_SetSecretCount[] = "SetSecretCount";
|
||||
static constexpr char ScriptReserved_SetTotalSecretCount[] = "SetTotalSecretCount";
|
||||
|
@ -176,6 +191,7 @@ static constexpr char ScriptReserved_EnableFlyCheat[] = "EnableFlyCheat";
|
|||
static constexpr char ScriptReserved_EnableMassPickup[] = "EnableMassPickup";
|
||||
static constexpr char ScriptReserved_EnableLaraInTitle[] = "EnableLaraInTitle";
|
||||
static constexpr char ScriptReserved_EnableLevelSelect[] = "EnableLevelSelect";
|
||||
static constexpr char ScriptReserved_EnableLoadSave[] = "EnableLoadSave";
|
||||
static constexpr char ScriptReserved_EnablePointFilter[] = "EnablePointFilter";
|
||||
|
||||
// Flow Functions
|
||||
|
@ -230,8 +246,9 @@ static constexpr char ScriptReserved_HasLineOfSight[] = "HasLineOfSight";
|
|||
|
||||
static constexpr char ScriptReserved_AddCallback[] = "AddCallback";
|
||||
static constexpr char ScriptReserved_RemoveCallback[] = "RemoveCallback";
|
||||
static constexpr char ScriptReserved_HandleEvent[] = "HandleEvent";
|
||||
|
||||
static constexpr char ScriptReserved_DisplayScreenSprite[] = "DisplayScreenSprite";
|
||||
static constexpr char ScriptReserved_DrawDisplaySprite[] = "DrawDisplaySprite";
|
||||
static constexpr char ScriptReserved_EmitParticle[] = "EmitParticle";
|
||||
static constexpr char ScriptReserved_EmitLightningArc[] = "EmitLightningArc";
|
||||
static constexpr char ScriptReserved_EmitShockwave[] = "EmitShockwave";
|
||||
|
@ -281,6 +298,7 @@ static constexpr char ScriptReserved_RoomReverb[] = "RoomReverb";
|
|||
static constexpr char ScriptReserved_DisplayStringOption[] = "DisplayStringOption";
|
||||
static constexpr char ScriptReserved_CallbackPoint[] = "CallbackPoint";
|
||||
static constexpr char ScriptReserved_EndReason[] = "EndReason";
|
||||
static constexpr char ScriptReserved_EventType[] = "EventType";
|
||||
|
||||
static constexpr char ScriptReserved_LevelVars[] = "LevelVars";
|
||||
static constexpr char ScriptReserved_GameVars[] = "GameVars";
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include "Scripting/Include/ScriptInterfaceState.h"
|
||||
|
||||
#include "Scripting/Internal/ReservedScriptNames.h"
|
||||
#include "Scripting/Internal/TEN/DisplaySprite/ScriptDisplaySprite.h"
|
||||
#include "Scripting/Internal/TEN/Effects/EffectsFunctions.h"
|
||||
#include "Scripting/Internal/TEN/Flow/FlowHandler.h"
|
||||
#include "Scripting/Internal/TEN/Inventory/InventoryHandler.h"
|
||||
|
@ -10,8 +11,10 @@
|
|||
#include "Scripting/Internal/TEN/Objects/ObjectsHandler.h"
|
||||
#include "Scripting/Internal/TEN/Strings/StringsHandler.h"
|
||||
|
||||
static sol::state s_solState;
|
||||
static sol::table s_rootTable;
|
||||
using namespace TEN::Scripting::DisplaySprite;
|
||||
|
||||
static sol::state SolState;
|
||||
static sol::table RootTable;
|
||||
|
||||
int lua_exception_handler(lua_State* luaStatePtr, sol::optional<const std::exception&> exception, sol::string_view description)
|
||||
{
|
||||
|
@ -20,36 +23,40 @@ int lua_exception_handler(lua_State* luaStatePtr, sol::optional<const std::excep
|
|||
|
||||
ScriptInterfaceGame* ScriptInterfaceState::CreateGame()
|
||||
{
|
||||
return new LogicHandler(&s_solState, s_rootTable);
|
||||
return new LogicHandler(&SolState, RootTable);
|
||||
}
|
||||
|
||||
ScriptInterfaceFlowHandler* ScriptInterfaceState::CreateFlow()
|
||||
{
|
||||
return new FlowHandler(&s_solState, s_rootTable);
|
||||
return new FlowHandler(&SolState, RootTable);
|
||||
}
|
||||
|
||||
ScriptInterfaceObjectsHandler* ScriptInterfaceState::CreateObjectsHandler()
|
||||
{
|
||||
return new ObjectsHandler(&s_solState, s_rootTable);
|
||||
return new ObjectsHandler(&SolState, RootTable);
|
||||
}
|
||||
|
||||
ScriptInterfaceStringsHandler* ScriptInterfaceState::CreateStringsHandler()
|
||||
{
|
||||
return new StringsHandler(&s_solState, s_rootTable);
|
||||
return new StringsHandler(&SolState, RootTable);
|
||||
}
|
||||
|
||||
void ScriptInterfaceState::Init(const std::string& assetsDir)
|
||||
{
|
||||
s_solState.open_libraries(sol::lib::base, sol::lib::math, sol::lib::package, sol::lib::coroutine, sol::lib::table, sol::lib::string, sol::lib::debug);
|
||||
SolState.open_libraries(
|
||||
sol::lib::base, sol::lib::math, sol::lib::package, sol::lib::coroutine,
|
||||
sol::lib::table, sol::lib::string, sol::lib::debug);
|
||||
|
||||
s_solState.script("package.path=\"" + assetsDir + "Scripts/?.lua\"");
|
||||
s_solState.set_exception_handler(lua_exception_handler);
|
||||
SolState.script("package.path=\"" + assetsDir + "Scripts/?.lua\"");
|
||||
SolState.set_exception_handler(lua_exception_handler);
|
||||
|
||||
s_rootTable = sol::table{ s_solState.lua_state(), sol::create };
|
||||
s_solState.set(ScriptReserved_TEN, s_rootTable);
|
||||
RootTable = sol::table(SolState.lua_state(), sol::create);
|
||||
SolState.set(ScriptReserved_TEN, RootTable);
|
||||
|
||||
// Misc. handlers not assigned above.
|
||||
InventoryHandler::Register(&s_solState, s_rootTable);
|
||||
Misc::Register(&s_solState, s_rootTable);
|
||||
Effects::Register(&s_solState, s_rootTable);
|
||||
InventoryHandler::Register(&SolState, RootTable);
|
||||
Misc::Register(&SolState, RootTable);
|
||||
Effects::Register(&SolState, RootTable);
|
||||
|
||||
ScriptDisplaySprite::RegisterTables(&SolState, RootTable);
|
||||
}
|
||||
|
|
|
@ -28,9 +28,9 @@
|
|||
// This alias is an effort to avoid the above problems.
|
||||
template <typename ... Ts> using TypeOrNil = std::variant<Ts..., sol::nil_t, sol::object>;
|
||||
|
||||
// To be used with TypeOrNil to fill arguments with default values if said arguments weren't given by the script.
|
||||
#define USE_IF_HAVE(Type, ifThere, ifNotThere) \
|
||||
(std::holds_alternative<Type>(ifThere) ? std::get<Type>(ifThere) : ifNotThere)
|
||||
// Used with TypeOrNil to fill arguments with default values if arguments in script not provided.
|
||||
#define USE_IF_HAVE(Type, valueIfExists, valueIfMissing) \
|
||||
(std::holds_alternative<Type>(valueIfExists) ? std::get<Type>(valueIfExists) : valueIfMissing)
|
||||
|
||||
sol::table MakeSpecialTableBase(sol::state* state, std::string const& name);
|
||||
|
||||
|
|
50
TombEngine/Scripting/Internal/TEN/DisplaySprite/AlignModes.h
Normal file
50
TombEngine/Scripting/Internal/TEN/DisplaySprite/AlignModes.h
Normal file
|
@ -0,0 +1,50 @@
|
|||
#pragma once
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "Game/Effects/DisplaySprite.h"
|
||||
|
||||
using namespace TEN::Effects::DisplaySprite;
|
||||
|
||||
namespace TEN::Scripting::DisplaySprite
|
||||
{
|
||||
/***
|
||||
Constants for display sprite align modes.
|
||||
@enum DisplaySprite.AlignMode
|
||||
@pragma nostrip
|
||||
*/
|
||||
|
||||
/*** DisplaySprite.AlignMode constants.
|
||||
|
||||
The following constants are inside AlignMode.
|
||||
|
||||
CENTER
|
||||
CENTER_TOP
|
||||
CENTER_BOTTOM
|
||||
CENTER_LEFT
|
||||
CENTER_RIGHT
|
||||
TOP_LEFT
|
||||
TOP_RIGHT
|
||||
BOTTOM_LEFT
|
||||
BOTTOM_RIGHT
|
||||
|
||||
@section DisplaySprite.AlignMode
|
||||
*/
|
||||
|
||||
/*** Table of display sprite align modes.
|
||||
@table CONSTANT_STRING_HERE
|
||||
*/
|
||||
|
||||
static const std::unordered_map<std::string, DisplaySpriteAlignMode> DISPLAY_SPRITE_ALIGN_MODES
|
||||
{
|
||||
{ "CENTER", DisplaySpriteAlignMode::Center },
|
||||
{ "CENTER_TOP", DisplaySpriteAlignMode::CenterTop },
|
||||
{ "CENTER_BOTTOM", DisplaySpriteAlignMode::CenterBottom },
|
||||
{ "CENTER_LEFT", DisplaySpriteAlignMode::CenterLeft },
|
||||
{ "CENTER_RIGHT", DisplaySpriteAlignMode::CenterRight },
|
||||
{ "TOP_LEFT", DisplaySpriteAlignMode::TopLeft },
|
||||
{ "TOP_RIGHT", DisplaySpriteAlignMode::TopRight },
|
||||
{ "BOTTOM_LEFT", DisplaySpriteAlignMode::BottomLeft },
|
||||
{ "BOTTOM_RIGHT", DisplaySpriteAlignMode::BottomRight }
|
||||
};
|
||||
}
|
38
TombEngine/Scripting/Internal/TEN/DisplaySprite/ScaleModes.h
Normal file
38
TombEngine/Scripting/Internal/TEN/DisplaySprite/ScaleModes.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
#pragma once
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "Game/effects/DisplaySprite.h"
|
||||
|
||||
using namespace TEN::Effects::DisplaySprite;
|
||||
|
||||
namespace TEN::Scripting::DisplaySprite
|
||||
{
|
||||
/***
|
||||
Constants for display sprite scale modes.
|
||||
@enum DisplaySprite.ScaleMode
|
||||
@pragma nostrip
|
||||
*/
|
||||
|
||||
/*** DisplaySprite.ScaleMode constants.
|
||||
|
||||
The following constants are inside DisplaySprite.ScaleMode.
|
||||
|
||||
FIT
|
||||
FILL
|
||||
STRETCH
|
||||
|
||||
@section DisplaySprite.ScaleMode
|
||||
*/
|
||||
|
||||
/*** Table of display sprite scale modes.
|
||||
@table CONSTANT_STRING_HERE
|
||||
*/
|
||||
|
||||
static const std::unordered_map<std::string, DisplaySpriteScaleMode> DISPLAY_SPRITE_SCALE_MODES
|
||||
{
|
||||
{ "FIT", DisplaySpriteScaleMode::Fit },
|
||||
{ "FILL", DisplaySpriteScaleMode::Fill },
|
||||
{ "STRETCH", DisplaySpriteScaleMode::Stretch }
|
||||
};
|
||||
}
|
|
@ -0,0 +1,138 @@
|
|||
#include "framework.h"
|
||||
#include "Scripting/Internal/TEN/DisplaySprite/ScriptDisplaySprite.h"
|
||||
|
||||
#include "Game/effects/DisplaySprite.h"
|
||||
#include "Game/Setup.h"
|
||||
#include "Objects/game_object_ids.h"
|
||||
#include "Scripting/Internal/LuaHandler.h"
|
||||
#include "Scripting/Internal/ReservedScriptNames.h"
|
||||
#include "Scripting/Internal/TEN/Color/Color.h"
|
||||
#include "Scripting/Internal/TEN/DisplaySprite/AlignModes.h"
|
||||
#include "Scripting/Internal/TEN/DisplaySprite/ScaleModes.h"
|
||||
#include "Scripting/Internal/TEN/Vec2/Vec2.h"
|
||||
|
||||
using namespace TEN::Effects::DisplaySprite;
|
||||
|
||||
namespace TEN::Scripting::DisplaySprite
|
||||
{
|
||||
void ScriptDisplaySprite::Register(sol::table& parent)
|
||||
{
|
||||
using ctors = sol::constructors<ScriptDisplaySprite(GAME_OBJECT_ID, int, const Vec2&, float, const Vec2&, sol::optional<const ScriptColor&>)>;
|
||||
|
||||
parent.new_usertype<ScriptDisplaySprite>(
|
||||
ScriptReserved_DisplaySprite,
|
||||
ctors(),
|
||||
sol::call_constructor, ctors(),
|
||||
|
||||
ScriptReserved_DisplaySpriteDraw, &ScriptDisplaySprite::Draw,
|
||||
|
||||
/// (Objects.ObjID) ID of the sprite sequence object.
|
||||
//@mem ObjectID
|
||||
"ObjectID", &ScriptDisplaySprite::ObjectID,
|
||||
|
||||
/// (int) ID of the sprite in the sprite sequence object.
|
||||
//@mem SpriteID
|
||||
"SpriteID", &ScriptDisplaySprite::SpriteID,
|
||||
|
||||
/// (Vec2) Display space position of the display sprite in percent. Alignment determined by __DisplaySprite.AlignMode__
|
||||
//@mem Position
|
||||
"Position", &ScriptDisplaySprite::Position,
|
||||
|
||||
/// (float) Rotation of the display sprite in degrees.
|
||||
//@mem Rotation
|
||||
"Rotation", &ScriptDisplaySprite::Rotation,
|
||||
|
||||
/// (Vec2) Horizontal and vertical scale of the display sprite in percent. Relative to __DisplaySprite.ScaleMode__.
|
||||
//@mem Scale
|
||||
"Scale", &ScriptDisplaySprite::Scale,
|
||||
|
||||
/// (Color) Color of the display sprite.
|
||||
//@mem Color
|
||||
"Color", &ScriptDisplaySprite::Color);
|
||||
}
|
||||
|
||||
void ScriptDisplaySprite::RegisterTables(sol::state* state, sol::table& parent)
|
||||
{
|
||||
auto table = sol::table(state->lua_state(), sol::create);
|
||||
parent.set(ScriptReserved_DisplaySprite, table);
|
||||
|
||||
auto handler = LuaHandler(state);
|
||||
handler.MakeReadOnlyTable(table, ScriptReserved_DisplaySpriteTableAlignMode, DISPLAY_SPRITE_ALIGN_MODES);
|
||||
handler.MakeReadOnlyTable(table, ScriptReserved_DisplaySpriteTableScaleMode, DISPLAY_SPRITE_SCALE_MODES);
|
||||
}
|
||||
|
||||
/***
|
||||
@int objectID ID of the sprite sequence object.
|
||||
@int spriteID ID of the sprite in the sprite sequence object.
|
||||
@Vec2 pos Display space position of the display sprite in percent. Alignment determined by __DisplaySprite.AlignMode__
|
||||
@float rot Rotation of the display sprite in degrees.
|
||||
@Vec2 scale Horizontal and vertical scale of the display sprite in percent. Relative to __DisplaySprite.ScaleMode__.
|
||||
@Color color[opt] Color of the display sprite. __Default: Color(255, 255, 255, 255)__
|
||||
@treturn DisplaySprite A DisplaySprite object.
|
||||
*/
|
||||
ScriptDisplaySprite::ScriptDisplaySprite(GAME_OBJECT_ID objectID, int spriteID, const Vec2& pos, float rot, const Vec2& scale,
|
||||
sol::optional<const ScriptColor&> color)
|
||||
{
|
||||
static const auto DEFAULT_COLOR = ScriptColor(255, 255, 255, 255);
|
||||
|
||||
ObjectID = objectID;
|
||||
SpriteID = spriteID;
|
||||
Position = pos;
|
||||
Rotation = rot;
|
||||
Scale = scale;
|
||||
Color = color.value_or(DEFAULT_COLOR);
|
||||
}
|
||||
|
||||
/*** Draw the display sprite in display space for the current frame.
|
||||
@function DisplaySprite:Draw
|
||||
@tparam Objects.ObjID[opt] priority Draw priority of the sprite. Can be thought of as a layer, with higher values having higher priority. __Default: 0__
|
||||
@tparam DisplaySprite.AlignMode[opt] alignMode Align mode of the sprite. __Default: DisplaySprite.AlignMode.CENTER__
|
||||
@tparam DisplaySprite.ScaleMode[opt] scaleMode Scale mode of the sprite. __Default: DisplaySprite.ScaleMode.FIT__
|
||||
@tparam Effects.BlendID[opt] blendMode Blend mode of the sprite. __Default: Effects.BlendID.ALPHABLEND__
|
||||
*/
|
||||
void ScriptDisplaySprite::Draw(sol::optional<int> priority, sol::optional<DisplaySpriteAlignMode> alignMode,
|
||||
sol::optional<DisplaySpriteScaleMode> scaleMode, sol::optional<BLEND_MODES> blendMode)
|
||||
{
|
||||
// NOTE: Conversion from more intuitive 100x100 screen space resolution to internal 800x600 is required.
|
||||
// In a future refactor, everything will use 100x100 natively. -- Sezz 2023.08.31
|
||||
constexpr auto POS_CONVERSION_COEFF = Vector2(SCREEN_SPACE_RES.x / 100, SCREEN_SPACE_RES.y / 100);
|
||||
constexpr auto SCALE_CONVERSION_COEFF = 0.01f;
|
||||
|
||||
constexpr auto DEFAULT_PRIORITY = 0;
|
||||
constexpr auto DEFAULT_ALIGN_MODE = DisplaySpriteAlignMode::Center;
|
||||
constexpr auto DEFAULT_SCALE_MODE = DisplaySpriteScaleMode::Fit;
|
||||
constexpr auto DEFAULT_BLEND_MODE = BLENDMODE_ALPHABLEND;
|
||||
|
||||
// Object is not a sprite object; return early.
|
||||
if (ObjectID < GAME_OBJECT_ID::ID_HORIZON || ObjectID >= GAME_OBJECT_ID::ID_NUMBER_OBJECTS)
|
||||
{
|
||||
TENLog("Attempted to draw display sprite from non-sprite sequence object " + std::to_string(ObjectID), LogLevel::Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
// Sprite missing or sequence not found; return early.
|
||||
const auto& object = Objects[ObjectID];
|
||||
if (!object.loaded || SpriteID >= abs(object.nmeshes))
|
||||
{
|
||||
TENLog(
|
||||
"Attempted to draw missing sprite " + std::to_string(SpriteID) +
|
||||
" from sprite sequence object " + std::to_string(ObjectID) +
|
||||
" as display sprite.",
|
||||
LogLevel::Warning);
|
||||
return;
|
||||
}
|
||||
|
||||
auto convertedPos = Vector2(Position.x, Position.y) * POS_CONVERSION_COEFF;
|
||||
short convertedRot = ANGLE(Rotation);
|
||||
auto convertedScale = Vector2(Scale.x, Scale.y) * SCALE_CONVERSION_COEFF;
|
||||
auto convertedColor = Vector4(Color.GetR(), Color.GetG(), Color.GetB(), Color.GetA()) / UCHAR_MAX;
|
||||
|
||||
AddDisplaySprite(
|
||||
ObjectID, SpriteID,
|
||||
convertedPos, convertedRot, convertedScale, convertedColor,
|
||||
priority.value_or(DEFAULT_PRIORITY),
|
||||
alignMode.value_or(DEFAULT_ALIGN_MODE),
|
||||
scaleMode.value_or(DEFAULT_SCALE_MODE),
|
||||
blendMode.value_or(DEFAULT_BLEND_MODE));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
#pragma once
|
||||
#include "Game/effects/DisplaySprite.h"
|
||||
#include "Objects/game_object_ids.h"
|
||||
#include "Scripting/Internal/TEN/Color/Color.h"
|
||||
#include "Scripting/Internal/TEN/Vec2/Vec2.h"
|
||||
|
||||
enum BLEND_MODE;
|
||||
|
||||
using namespace TEN::Effects::DisplaySprite;
|
||||
|
||||
// TODO:
|
||||
// Check if align modes are applied correctly.
|
||||
// Check if ScriptDisplaySprite object has been registered correctly.
|
||||
// Check if its methods have been registered correctly.
|
||||
// Register DISPLAY_SPRITE_SCALE_MODES and DISPLAY_SPRITE_ORIGIN_TYPES under the correct sub-thing.
|
||||
// Test nested sprites in various modes and how they behave when the aspect ratio changes.
|
||||
// Check with everyone if the mySprite.Draw(blah, blah, blah) syntax is sensible.
|
||||
|
||||
namespace TEN::Scripting::DisplaySprite
|
||||
{
|
||||
class ScriptDisplaySprite
|
||||
{
|
||||
public:
|
||||
static void Register(sol::table& parent);
|
||||
static void RegisterTables(sol::state* state, sol::table& parent);
|
||||
|
||||
// Members
|
||||
GAME_OBJECT_ID ObjectID = GAME_OBJECT_ID::ID_DEFAULT_SPRITES;
|
||||
int SpriteID = 0;
|
||||
|
||||
Vec2 Position = Vec2(0.0f, 0.0f);
|
||||
float Rotation = 0.0f;
|
||||
Vec2 Scale = Vec2(0.0f, 0.0f);
|
||||
ScriptColor Color = ScriptColor(255, 255, 255, 255);
|
||||
|
||||
// Constructors
|
||||
ScriptDisplaySprite(GAME_OBJECT_ID objectID, int spriteID, const Vec2& pos, float rot, const Vec2& scale,
|
||||
sol::optional<const ScriptColor&> color);
|
||||
|
||||
// Utilities
|
||||
void Draw(sol::optional<int> priority, sol::optional<DisplaySpriteAlignMode> alignMode,
|
||||
sol::optional<DisplaySpriteScaleMode> scaleMode, sol::optional<BLEND_MODES> blendMode);
|
||||
};
|
||||
}
|
|
@ -1,10 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
// Last generated on 31/7/2022.
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "Renderer/Renderer11Enums.h"
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
|
||||
/***
|
||||
Constants for blend mode IDs.
|
||||
|
@ -34,17 +32,16 @@ The following constants are inside BlendID.
|
|||
@table CONSTANT_STRING_HERE
|
||||
*/
|
||||
|
||||
|
||||
static const std::unordered_map<std::string, BLEND_MODES> BLEND_IDS
|
||||
{
|
||||
{"OPAQUE", BLENDMODE_OPAQUE},
|
||||
{"ALPHATEST", BLENDMODE_ALPHATEST},
|
||||
{"ADDITIVE", BLENDMODE_ADDITIVE},
|
||||
{"NOZTEST", BLENDMODE_NOZTEST},
|
||||
{"SUBTRACTIVE", BLENDMODE_SUBTRACTIVE},
|
||||
{"WIREFRAME", BLENDMODE_WIREFRAME},
|
||||
{"EXCLUDE", BLENDMODE_EXCLUDE},
|
||||
{"SCREEN", BLENDMODE_SCREEN},
|
||||
{"LIGHTEN", BLENDMODE_LIGHTEN},
|
||||
{"ALPHABLEND", BLENDMODE_ALPHABLEND}
|
||||
{ "OPAQUE", BLENDMODE_OPAQUE },
|
||||
{ "ALPHATEST", BLENDMODE_ALPHATEST },
|
||||
{ "ADDITIVE", BLENDMODE_ADDITIVE },
|
||||
{ "NOZTEST", BLENDMODE_NOZTEST },
|
||||
{ "SUBTRACTIVE", BLENDMODE_SUBTRACTIVE },
|
||||
{ "WIREFRAME", BLENDMODE_WIREFRAME },
|
||||
{ "EXCLUDE", BLENDMODE_EXCLUDE },
|
||||
{ "SCREEN", BLENDMODE_SCREEN },
|
||||
{ "LIGHTEN", BLENDMODE_LIGHTEN },
|
||||
{ "ALPHABLEND", BLENDMODE_ALPHABLEND }
|
||||
};
|
||||
|
|
|
@ -32,11 +32,11 @@ The following constants are inside EffectID.
|
|||
|
||||
static const std::unordered_map<std::string, EffectType> EFFECT_IDS
|
||||
{
|
||||
{"NONE", EffectType::None},
|
||||
{"FIRE", EffectType::Fire},
|
||||
{"SPARKS", EffectType::Sparks},
|
||||
{"SMOKE", EffectType::Smoke},
|
||||
{"ELECTRICIGNITE", EffectType::ElectricIgnite},
|
||||
{"REDIGNITE", EffectType::RedIgnite},
|
||||
{"CUSTOM", EffectType::Custom}
|
||||
{ "NONE", EffectType::None },
|
||||
{ "FIRE", EffectType::Fire },
|
||||
{ "SPARKS", EffectType::Sparks },
|
||||
{ "SMOKE", EffectType::Smoke},
|
||||
{ "ELECTRICIGNITE", EffectType::ElectricIgnite },
|
||||
{ "REDIGNITE", EffectType::RedIgnite },
|
||||
{ "CUSTOM", EffectType::Custom }
|
||||
};
|
||||
|
|
|
@ -4,10 +4,10 @@
|
|||
#include "Game/camera.h"
|
||||
#include "Game/collision/collide_room.h"
|
||||
#include "Game/control/los.h"
|
||||
#include "Game/effects/DisplaySprite.h"
|
||||
#include "Game/effects/effects.h"
|
||||
#include "Game/effects/Electricity.h"
|
||||
#include "Game/effects/explosion.h"
|
||||
#include "Game/effects/ScreenSprite.h"
|
||||
#include "Game/effects/spark.h"
|
||||
#include "Game/effects/tomb4fx.h"
|
||||
#include "Game/effects/weather.h"
|
||||
|
@ -30,47 +30,14 @@ Functions to generate effects.
|
|||
@pragma nostrip
|
||||
*/
|
||||
|
||||
using namespace TEN::Effects::DisplaySprite;
|
||||
using namespace TEN::Effects::Electricity;
|
||||
using namespace TEN::Effects::Environment;
|
||||
using namespace TEN::Effects::Explosion;
|
||||
using namespace TEN::Effects::ScreenSprite;
|
||||
using namespace TEN::Effects::Spark;
|
||||
|
||||
namespace Effects
|
||||
{
|
||||
/// Display a sprite on the screen.
|
||||
//@function DisplayScreenSprite
|
||||
//@tparam int objectID Object ID of the sprite.
|
||||
//@tparam int spriteIndex Index of the sprite in the sprite object.
|
||||
//@tparam Vec2 pos 2D position of the sprite. NOTE: Screen space resolution is 100x100.
|
||||
//@tparam float rot Rotation of the sprite in degrees. Default is 0.
|
||||
//@tparam Vec2 size Size of the sprite.
|
||||
//@tparam Color color Color of the sprite. Default is Color(255, 255, 255, 255).
|
||||
//@tparam int priority Render priority of the sprite. Higher values have higher priority. Default is 0.
|
||||
//@tparam Effects.BlendID blendMode Blend mode of the sprite. Default is TEN.Effects.BlendID.ALPHABLEND.
|
||||
static void DisplayScreenSprite(GAME_OBJECT_ID objectID, int spriteIndex, const Vec2& pos, TypeOrNil<float> rot, const Vec2& size,
|
||||
TypeOrNil<ScriptColor> color, TypeOrNil<int> priority, TypeOrNil<BLEND_MODES> blendMode)
|
||||
{
|
||||
// NOTE: Conversion from more intuitive 100x100 screen space resolution to internal 800x600 is required.
|
||||
// Later, everything will be natively 100x100. -- Sezz 2023.08.31
|
||||
constexpr auto POS_CONVERSION_COEFF = Vector2(SCREEN_SPACE_RES.x / 100, SCREEN_SPACE_RES.y / 100);
|
||||
|
||||
auto scriptColor = USE_IF_HAVE(ScriptColor, color, ScriptColor(255, 255, 255, 255));
|
||||
|
||||
auto bMode = USE_IF_HAVE(BLEND_MODES, blendMode, BLENDMODE_ALPHABLEND);
|
||||
bMode = BLEND_MODES(std::clamp((int)bMode, (int)BLEND_MODES::BLENDMODE_OPAQUE, (int)BLEND_MODES::BLENDMODE_ALPHABLEND));
|
||||
|
||||
AddScreenSprite(
|
||||
objectID,
|
||||
spriteIndex,
|
||||
Vector2(pos.x, pos.y) * POS_CONVERSION_COEFF,
|
||||
ANGLE(USE_IF_HAVE(float, rot, 0.0f)),
|
||||
Vector2(size.x, size.y),
|
||||
Vector4(scriptColor.GetR(), scriptColor.GetG(), scriptColor.GetB(), scriptColor.GetA()) / UCHAR_MAX,
|
||||
USE_IF_HAVE(int, priority, 0),
|
||||
bMode);
|
||||
}
|
||||
|
||||
///Emit a lightning arc.
|
||||
//@function EmitLightningArc
|
||||
//@tparam Vec3 src
|
||||
|
@ -354,12 +321,11 @@ namespace Effects
|
|||
Weather.Flash(color.GetR(), color.GetG(), color.GetB(), (USE_IF_HAVE(float, speed, 1.0)) / (float)FPS);
|
||||
}
|
||||
|
||||
void Register(sol::state* state, sol::table& parent)
|
||||
void Register(sol::state* state, sol::table& parent)
|
||||
{
|
||||
sol::table tableEffects = { state->lua_state(), sol::create };
|
||||
auto tableEffects = sol::table(state->lua_state(), sol::create);
|
||||
parent.set(ScriptReserved_Effects, tableEffects);
|
||||
|
||||
tableEffects.set_function(ScriptReserved_DisplayScreenSprite, &DisplayScreenSprite);
|
||||
tableEffects.set_function(ScriptReserved_EmitLightningArc, &EmitLightningArc);
|
||||
tableEffects.set_function(ScriptReserved_EmitParticle, &EmitParticle);
|
||||
tableEffects.set_function(ScriptReserved_EmitShockwave, &EmitShockwave);
|
||||
|
@ -370,7 +336,7 @@ namespace Effects
|
|||
tableEffects.set_function(ScriptReserved_FlashScreen, &FlashScreen);
|
||||
tableEffects.set_function(ScriptReserved_MakeEarthquake, &Earthquake);
|
||||
|
||||
LuaHandler handler{ state };
|
||||
auto handler = LuaHandler{ state };
|
||||
handler.MakeReadOnlyTable(tableEffects, ScriptReserved_BlendID, BLEND_IDS);
|
||||
handler.MakeReadOnlyTable(tableEffects, ScriptReserved_EffectID, EFFECT_IDS);
|
||||
}
|
||||
|
|
|
@ -20,5 +20,5 @@ struct Animations
|
|||
bool HasOverhangClimb; // Overhang functionality.
|
||||
bool HasLedgeJumps; // Jump up or back from a ledge.
|
||||
|
||||
static void Register(sol::table &);
|
||||
static void Register(sol::table&);
|
||||
};
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "Scripting/Include/Objects/ScriptInterfaceObjectsHandler.h"
|
||||
#include "Scripting/Include/Strings/ScriptInterfaceStringsHandler.h"
|
||||
#include "Scripting/Internal/ReservedScriptNames.h"
|
||||
#include "Scripting/Internal/TEN/DisplaySprite/ScriptDisplaySprite.h"
|
||||
#include "Scripting/Internal/TEN/Flow/InventoryItem/InventoryItem.h"
|
||||
#include "Scripting/Internal/TEN/Logic/LevelFunc.h"
|
||||
#include "Scripting/Internal/TEN/Vec2/Vec2.h"
|
||||
|
@ -15,6 +16,8 @@
|
|||
#include "Sound/sound.h"
|
||||
#include "Specific/trutils.h"
|
||||
|
||||
using namespace TEN::Scripting::DisplaySprite;
|
||||
|
||||
/***
|
||||
Functions that (mostly) don't directly impact in-game mechanics. Used for setup
|
||||
in gameflow.lua, settings.lua and strings.lua; some can be used in level
|
||||
|
@ -28,7 +31,8 @@ ScriptInterfaceObjectsHandler* g_GameScriptEntities;
|
|||
ScriptInterfaceStringsHandler* g_GameStringsHandler;
|
||||
ScriptInterfaceFlowHandler* g_GameFlow;
|
||||
|
||||
FlowHandler::FlowHandler(sol::state* lua, sol::table& parent) : m_handler(lua)
|
||||
FlowHandler::FlowHandler(sol::state* lua, sol::table& parent) :
|
||||
m_handler(lua)
|
||||
{
|
||||
/*** gameflow.lua.
|
||||
These functions are called in gameflow.lua, a file loosely equivalent to winroomedit's SCRIPT.DAT.
|
||||
|
@ -75,6 +79,12 @@ Must be true or false
|
|||
*/
|
||||
tableFlow.set_function(ScriptReserved_EnableLevelSelect, &FlowHandler::EnableLevelSelect, this);
|
||||
|
||||
/*** Enable or disable saving and loading of savegames.
|
||||
@function EnableLoadSave
|
||||
@tparam bool enabled true or false.
|
||||
*/
|
||||
tableFlow.set_function(ScriptReserved_EnableLoadSave, &FlowHandler::EnableLoadSave, this);
|
||||
|
||||
/*** gameflow.lua or level scripts.
|
||||
@section FlowluaOrScripts
|
||||
*/
|
||||
|
@ -124,6 +134,35 @@ level count, jumps to title.
|
|||
*/
|
||||
tableFlow.set_function(ScriptReserved_EndLevel, &FlowHandler::EndLevel, this);
|
||||
|
||||
/***
|
||||
Save the game to a savegame slot.
|
||||
@function SaveGame
|
||||
@tparam int slotID ID of the savegame slot to save to.
|
||||
*/
|
||||
tableFlow.set_function(ScriptReserved_SaveGame, &FlowHandler::SaveGame, this);
|
||||
|
||||
/***
|
||||
Load the game from a savegame slot.
|
||||
@function LoadGame
|
||||
@tparam int slotID ID of the savegame slot to load from.
|
||||
*/
|
||||
tableFlow.set_function(ScriptReserved_LoadGame, &FlowHandler::LoadGame, this);
|
||||
|
||||
/***
|
||||
Delete a savegame.
|
||||
@function DeleteSaveGame
|
||||
@tparam int slotID ID of the savegame slot to clear.
|
||||
*/
|
||||
tableFlow.set_function(ScriptReserved_DeleteSaveGame, &FlowHandler::DeleteSaveGame, this);
|
||||
|
||||
/***
|
||||
Check if a savegame exists.
|
||||
@function DoesSaveGameExist
|
||||
@tparam int slotID ID of the savegame slot to check.
|
||||
@treturn bool true if the savegame exists, false if not.
|
||||
*/
|
||||
tableFlow.set_function(ScriptReserved_DoesSaveGameExist, &FlowHandler::DoesSaveGameExist, this);
|
||||
|
||||
/***
|
||||
Returns the player's current per-game secret count.
|
||||
@function GetSecretCount
|
||||
|
@ -195,6 +234,7 @@ Specify which translations in the strings table correspond to which languages.
|
|||
tableFlow.set_function(ScriptReserved_SetLanguageNames, &FlowHandler::SetLanguageNames, this);
|
||||
|
||||
ScriptColor::Register(parent);
|
||||
ScriptDisplaySprite::Register(parent);
|
||||
Rotation::Register(parent);
|
||||
Vec2::Register(parent);
|
||||
Vec3::Register(parent);
|
||||
|
@ -206,11 +246,11 @@ Specify which translations in the strings table correspond to which languages.
|
|||
Settings::Register(tableFlow);
|
||||
Fog::Register(tableFlow);
|
||||
|
||||
m_handler.MakeReadOnlyTable(tableFlow, ScriptReserved_WeatherType, kWeatherTypes);
|
||||
m_handler.MakeReadOnlyTable(tableFlow, ScriptReserved_LaraType, kLaraTypes);
|
||||
m_handler.MakeReadOnlyTable(tableFlow, ScriptReserved_WeatherType, WEATHER_TYPES);
|
||||
m_handler.MakeReadOnlyTable(tableFlow, ScriptReserved_LaraType, PLAYER_TYPES);
|
||||
m_handler.MakeReadOnlyTable(tableFlow, ScriptReserved_RotationAxis, ROTATION_AXES);
|
||||
m_handler.MakeReadOnlyTable(tableFlow, ScriptReserved_ItemAction, ITEM_MENU_ACTIONS);
|
||||
m_handler.MakeReadOnlyTable(tableFlow, ScriptReserved_ErrorMode, kErrorModes);
|
||||
m_handler.MakeReadOnlyTable(tableFlow, ScriptReserved_ErrorMode, ERROR_MODES);
|
||||
}
|
||||
|
||||
FlowHandler::~FlowHandler()
|
||||
|
@ -280,7 +320,7 @@ void FlowHandler::SetTotalSecretCount(int secretsNumber)
|
|||
void FlowHandler::LoadFlowScript()
|
||||
{
|
||||
m_handler.ExecuteScript(m_gameDir + "Scripts/Gameflow.lua");
|
||||
m_handler.ExecuteScript(m_gameDir + "Scripts/SystemStrings.lua");
|
||||
m_handler.ExecuteScript(m_gameDir + "Scripts/SystemStrings.lua", true);
|
||||
m_handler.ExecuteScript(m_gameDir + "Scripts/Strings.lua", true);
|
||||
m_handler.ExecuteScript(m_gameDir + "Scripts/Settings.lua", true);
|
||||
|
||||
|
@ -382,7 +422,30 @@ int FlowHandler::GetLevelNumber(const std::string& fileName)
|
|||
void FlowHandler::EndLevel(std::optional<int> nextLevel)
|
||||
{
|
||||
int index = (nextLevel.has_value() && nextLevel.value() != 0) ? nextLevel.value() : CurrentLevel + 1;
|
||||
LevelComplete = index;
|
||||
NextLevel = index;
|
||||
}
|
||||
|
||||
void FlowHandler::SaveGame(int slot)
|
||||
{
|
||||
SaveGame::Save(slot);
|
||||
}
|
||||
|
||||
void FlowHandler::LoadGame(int slot)
|
||||
{
|
||||
if (!SaveGame::DoesSaveGameExist(slot))
|
||||
return;
|
||||
|
||||
NextLevel = -(slot + 1);
|
||||
}
|
||||
|
||||
void FlowHandler::DeleteSaveGame(int slot)
|
||||
{
|
||||
SaveGame::Delete(slot);
|
||||
}
|
||||
|
||||
bool FlowHandler::DoesSaveGameExist(int slot)
|
||||
{
|
||||
return SaveGame::DoesSaveGameExist(slot, true);
|
||||
}
|
||||
|
||||
int FlowHandler::GetSecretCount() const
|
||||
|
@ -467,6 +530,16 @@ void FlowHandler::EnableLevelSelect(bool levelSelect)
|
|||
LevelSelect = levelSelect;
|
||||
}
|
||||
|
||||
bool FlowHandler::IsLoadSaveEnabled() const
|
||||
{
|
||||
return LoadSave;
|
||||
}
|
||||
|
||||
void FlowHandler::EnableLoadSave(bool loadSave)
|
||||
{
|
||||
LoadSave = loadSave;
|
||||
}
|
||||
|
||||
bool FlowHandler::DoFlow()
|
||||
{
|
||||
// We start with the title level, if no other index is specified
|
||||
|
@ -565,21 +638,22 @@ bool FlowHandler::DoFlow()
|
|||
|
||||
// Load level
|
||||
CurrentLevel = header.Level;
|
||||
NextLevel = 0;
|
||||
GameTimer = header.Timer;
|
||||
loadFromSavegame = true;
|
||||
break;
|
||||
|
||||
case GameStatus::LevelComplete:
|
||||
if (LevelComplete >= Levels.size())
|
||||
if (NextLevel >= Levels.size())
|
||||
{
|
||||
CurrentLevel = 0; // TODO: final credits
|
||||
}
|
||||
else
|
||||
{
|
||||
CurrentLevel = LevelComplete;
|
||||
CurrentLevel = NextLevel;
|
||||
}
|
||||
|
||||
LevelComplete = 0;
|
||||
NextLevel = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,17 +26,19 @@ private:
|
|||
LuaHandler m_handler;
|
||||
|
||||
public:
|
||||
int FogInDistance{ 0 };
|
||||
int FogOutDistance{ 0 };
|
||||
bool LevelSelect{ true };
|
||||
bool FlyCheat{ true };
|
||||
bool PointFilter{ false };
|
||||
bool MassPickup{ true };
|
||||
bool LaraInTitle{ false };
|
||||
bool DebugMode{ false };
|
||||
int FogInDistance = 0;
|
||||
int FogOutDistance = 0;
|
||||
|
||||
// New animation flag table
|
||||
Animations Anims{};
|
||||
bool LevelSelect = true;
|
||||
bool LoadSave = true;
|
||||
bool FlyCheat = true;
|
||||
bool PointFilter = false;
|
||||
bool MassPickup = true;
|
||||
bool LaraInTitle = false;
|
||||
bool DebugMode = false;
|
||||
|
||||
// Table for movesets.
|
||||
Animations Anims = {};
|
||||
|
||||
std::vector<Level*> Levels;
|
||||
|
||||
|
@ -58,6 +60,10 @@ public:
|
|||
int GetLevelNumber(const std::string& flieName);
|
||||
int GetNumLevels() const;
|
||||
void EndLevel(std::optional<int> nextLevel);
|
||||
void SaveGame(int slot);
|
||||
void LoadGame(int slot);
|
||||
void DeleteSaveGame(int slot);
|
||||
bool DoesSaveGameExist(int slot);
|
||||
int GetSecretCount() const;
|
||||
void SetSecretCount(int secretsNum);
|
||||
void AddSecret(int levelSecretIndex);
|
||||
|
@ -74,6 +80,8 @@ public:
|
|||
void EnableLaraInTitle(bool laraInTitle);
|
||||
bool IsLevelSelectEnabled() const;
|
||||
void EnableLevelSelect(bool laraInTitle);
|
||||
bool IsLoadSaveEnabled() const;
|
||||
void EnableLoadSave(bool loadSave);
|
||||
|
||||
bool HasCrawlExtended() const override { return Anims.HasCrawlExtended; }
|
||||
bool HasCrouchRoll() const override { return Anims.HasCrouchRoll; }
|
||||
|
|
|
@ -8,7 +8,7 @@ Fog
|
|||
@pragma nostrip
|
||||
*/
|
||||
|
||||
void Fog::Register(sol::table & parent)
|
||||
void Fog::Register(sol::table& parent)
|
||||
{
|
||||
using ctors = sol::constructors<Fog(ScriptColor const&, short, short)>;
|
||||
parent.new_usertype<Fog>("Fog",
|
||||
|
|
|
@ -20,5 +20,5 @@ struct Fog
|
|||
void SetColor(ScriptColor const& col);
|
||||
ScriptColor GetColor() const;
|
||||
|
||||
static void Register(sol::table &);
|
||||
static void Register(sol::table&);
|
||||
};
|
||||
|
|
|
@ -14,7 +14,7 @@ These are things things which aren't present in the compiled level file itself.
|
|||
@function Level
|
||||
@treturn Level a Level object
|
||||
*/
|
||||
void Level::Register(sol::table & parent)
|
||||
void Level::Register(sol::table& parent)
|
||||
{
|
||||
parent.new_usertype<Level>("Level",
|
||||
sol::constructors<Level()>(),
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#include "Scripting/Include/ScriptInterfaceLevel.h"
|
||||
#include "Scripting/Internal/TEN/Flow/InventoryItem/InventoryItem.h"
|
||||
|
||||
static const std::unordered_map<std::string, WeatherType> kWeatherTypes
|
||||
static const std::unordered_map<std::string, WeatherType> WEATHER_TYPES
|
||||
{
|
||||
{"None", WeatherType::None},
|
||||
{"Rain", WeatherType::Rain},
|
||||
|
@ -14,7 +14,7 @@ static const std::unordered_map<std::string, WeatherType> kWeatherTypes
|
|||
};
|
||||
|
||||
|
||||
static const std::unordered_map<std::string, LaraType> kLaraTypes
|
||||
static const std::unordered_map<std::string, LaraType> PLAYER_TYPES
|
||||
{
|
||||
{"Normal", LaraType::Normal},
|
||||
{"Young", LaraType::Young},
|
||||
|
@ -50,7 +50,7 @@ struct Level : public ScriptInterfaceLevel
|
|||
LaraType GetLaraType() const override;
|
||||
void SetWeatherStrength(float val);
|
||||
void SetLevelFarView(short val);
|
||||
static void Register(sol::table & parent);
|
||||
static void Register(sol::table& parent);
|
||||
WeatherType GetWeatherType() const override;
|
||||
short GetMirrorRoom() const override;
|
||||
short GetFogMinDistance() const override;
|
||||
|
|
|
@ -12,7 +12,7 @@ struct Mirror
|
|||
int StartZ{ 0 };
|
||||
int EndZ{ 0 };
|
||||
|
||||
static void Register(sol::table & parent);
|
||||
static void Register(sol::table& parent);
|
||||
Mirror() = default;
|
||||
|
||||
Mirror(short room, int startX, int endX, int startZ, int endZ);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#include "Scripting/Internal/ScriptAssert.h"
|
||||
#include <string>
|
||||
|
||||
static const std::unordered_map<std::string, ErrorMode> kErrorModes {
|
||||
static const std::unordered_map<std::string, ErrorMode> ERROR_MODES {
|
||||
{"SILENT", ErrorMode::Silent},
|
||||
{"WARN", ErrorMode::Warn},
|
||||
{"TERMINATE", ErrorMode::Terminate}
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
#include "framework.h"
|
||||
#include "Scripting/Internal/TEN/Inventory/InventoryHandler.h"
|
||||
|
||||
#include "InventoryHandler.h"
|
||||
#include "Scripting/Internal/ReservedScriptNames.h"
|
||||
#include "Game/Hud/Hud.h"
|
||||
#include "Game/Lara/lara.h"
|
||||
#include "Game/pickup/pickup.h"
|
||||
#include "Scripting/Internal/ReservedScriptNames.h"
|
||||
|
||||
using namespace TEN::Hud;
|
||||
|
||||
/***
|
||||
Inventory manipulation
|
||||
|
@ -12,70 +16,57 @@ Inventory manipulation
|
|||
|
||||
namespace InventoryHandler
|
||||
{
|
||||
///Add x of an item to the inventory.
|
||||
//Omitting the second argument will give the "default" amount of the item
|
||||
//(i.e. the amount the player would get from a pickup of that type).
|
||||
//For example, giving crossbow ammo without specifying the number would give the player
|
||||
//10 instead.
|
||||
//Has no effect if the player has an infinite number of that item.
|
||||
/// Add an item to the player's inventory.
|
||||
//@function GiveItem
|
||||
//@tparam Objects.ObjID item the item to be added
|
||||
//@int[opt] count the number of items to add (default: the amount you would get from a pickup)
|
||||
static void InventoryAdd(GAME_OBJECT_ID slot, sol::optional<int> count)
|
||||
//@tparam Objects.ObjID objectID Object ID of the item to add.
|
||||
//@int[opt] count The amount of items to add. Default is the yield from a single pickup, e.g. 1 from a medipack, 12 from a flare pack.
|
||||
//@bool[opt] addToPickupSummary If true, display the item in the pickup summary. Default is false.
|
||||
static void GiveItem(GAME_OBJECT_ID objectID, sol::optional<int> count, sol::optional<bool> addToPickupSummary)
|
||||
{
|
||||
// If nil is passed in, then the amount added will be the default amount
|
||||
// for that pickup - i.e. the amount you would get from picking up the
|
||||
// item in-game (e.g. 1 for medipacks, 12 for flares).
|
||||
|
||||
// can't use value_or(std::nullopt) here because nullopt isn't an int
|
||||
if (count.has_value())
|
||||
PickedUpObject(slot, count.value());
|
||||
else
|
||||
PickedUpObject(slot, std::nullopt);
|
||||
PickedUpObject(objectID, count.has_value() ? std::optional<int>(*count) : std::nullopt);
|
||||
|
||||
if (addToPickupSummary.value_or(false))
|
||||
{
|
||||
auto pos = GetJointPosition(LaraItem, LM_HIPS).ToVector3();
|
||||
g_Hud.PickupSummary.AddDisplayPickup(objectID, pos, count.value_or(1));
|
||||
}
|
||||
}
|
||||
|
||||
///Remove x of a certain item from the inventory.
|
||||
//As in @{GiveItem}, omitting the count will remove the "default" amount of that item.
|
||||
//Has no effect if the player has an infinite number of the item.
|
||||
/// Remove an item from the player's inventory.
|
||||
//@function TakeItem
|
||||
//@tparam Objects.ObjID item the item to be removed
|
||||
//@int[opt] count the number of items to remove (default: the amount you would get from a pickup)
|
||||
static void InventoryRemove(GAME_OBJECT_ID slot, sol::optional<int> count)
|
||||
//@tparam Objects.ObjID Object ID of the item to remove.
|
||||
//@int[opt] count The amount of items to remove. Default is the yield from a single pickup, e.g. 1 from a medipack, 12 from a flare pack.
|
||||
static void TakeItem(GAME_OBJECT_ID objectID, sol::optional<int> count)
|
||||
{
|
||||
//can't use value_or(std::nullopt) here because nullopt isn't an int
|
||||
if (count.has_value())
|
||||
RemoveObjectFromInventory(slot, count.value());
|
||||
else
|
||||
RemoveObjectFromInventory(slot, std::nullopt);
|
||||
RemoveObjectFromInventory(objectID, count.has_value() ? std::optional<int>(*count) : std::nullopt);
|
||||
}
|
||||
|
||||
///Get the amount the player holds of an item.
|
||||
/// Get the amount of an item held in the player's inventory.
|
||||
//@function GetItemCount
|
||||
//@tparam Objects.ObjID item the ID item to check
|
||||
//@treturn int the amount of the item the player has in the inventory. -1 indicates an infinite amount of that item.
|
||||
static int InventoryGetCount(GAME_OBJECT_ID slot)
|
||||
//@tparam Objects.ObjID objectID Object ID of the item to check.
|
||||
//@treturn int The amount of items. -1 indicates infinity.
|
||||
static int GetItemCount(GAME_OBJECT_ID objectID)
|
||||
{
|
||||
return GetInventoryCount(slot);
|
||||
return GetInventoryCount(objectID);
|
||||
}
|
||||
|
||||
///Set the amount of a certain item the player has in the inventory.
|
||||
//Similar to @{GiveItem} but replaces with the new amount instead of adding it.
|
||||
/// Set the amount of an item in the player's inventory.
|
||||
//@function SetItemCount
|
||||
//@tparam Objects.ObjID item the ID of the item to be set.
|
||||
//@tparam int count the number of items the player will have. A value of -1 will give an infinite amount of that item.
|
||||
static void InventorySetCount(GAME_OBJECT_ID slot, int count)
|
||||
//@tparam Objects.ObjID objectID Object ID of the item amount to set.
|
||||
//@tparam int count The amount of items to set. -1 indicates infinity.
|
||||
static void SetItemCount(GAME_OBJECT_ID objectID, int count)
|
||||
{
|
||||
SetInventoryCount(slot, count);
|
||||
SetInventoryCount(objectID, count);
|
||||
}
|
||||
|
||||
void Register(sol::state* state, sol::table& parent)
|
||||
{
|
||||
sol::table table_inventory{ state->lua_state(), sol::create };
|
||||
parent.set(ScriptReserved_Inventory, table_inventory);
|
||||
auto tableInventory = sol::table{ state->lua_state(), sol::create };
|
||||
parent.set(ScriptReserved_Inventory, tableInventory);
|
||||
|
||||
table_inventory.set_function(ScriptReserved_GiveInvItem, &InventoryAdd);
|
||||
table_inventory.set_function(ScriptReserved_TakeInvItem, &InventoryRemove);
|
||||
table_inventory.set_function(ScriptReserved_GetInvItemCount, &InventoryGetCount);
|
||||
table_inventory.set_function(ScriptReserved_SetInvItemCount, &InventorySetCount);
|
||||
tableInventory.set_function(ScriptReserved_GiveInvItem, &GiveItem);
|
||||
tableInventory.set_function(ScriptReserved_TakeInvItem, &TakeItem);
|
||||
tableInventory.set_function(ScriptReserved_GetInvItemCount, &GetItemCount);
|
||||
tableInventory.set_function(ScriptReserved_SetInvItemCount, &SetItemCount);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,17 +3,18 @@
|
|||
|
||||
#include <filesystem>
|
||||
|
||||
#include "Game/savegame.h"
|
||||
#include "Game/control/volume.h"
|
||||
#include "Game/effects/Electricity.h"
|
||||
#include "Game/savegame.h"
|
||||
#include "Scripting/Internal/ReservedScriptNames.h"
|
||||
#include "Scripting/Internal/ScriptAssert.h"
|
||||
#include "Scripting/Internal/ScriptUtil.h"
|
||||
#include "Scripting/Internal/TEN/Objects/Moveable/MoveableObject.h"
|
||||
#include "Scripting/Internal/TEN/Vec2/Vec2.h"
|
||||
#include "Scripting/Internal/TEN/Vec3/Vec3.h"
|
||||
#include "Scripting/Internal/TEN/Rotation/Rotation.h"
|
||||
#include "Scripting/Internal/TEN/Color/Color.h"
|
||||
#include "Scripting/Internal/TEN/Logic/LevelFunc.h"
|
||||
#include "Scripting/Internal/TEN/Objects/Moveable/MoveableObject.h"
|
||||
#include "Scripting/Internal/TEN/Rotation/Rotation.h"
|
||||
#include "Scripting/Internal/TEN/Vec2/Vec2.h"
|
||||
#include "Scripting/Internal/TEN/Vec3/Vec3.h"
|
||||
|
||||
using namespace TEN::Effects::Electricity;
|
||||
|
||||
|
@ -37,7 +38,7 @@ enum class CallbackPoint
|
|||
PostEnd
|
||||
};
|
||||
|
||||
static const std::unordered_map<std::string, CallbackPoint> kCallbackPoints
|
||||
static const std::unordered_map<std::string, CallbackPoint> CALLBACK_POINTS
|
||||
{
|
||||
{ ScriptReserved_PreStart, CallbackPoint::PreStart },
|
||||
{ ScriptReserved_PostStart, CallbackPoint::PostStart },
|
||||
|
@ -51,6 +52,13 @@ static const std::unordered_map<std::string, CallbackPoint> kCallbackPoints
|
|||
{ ScriptReserved_PostEnd, CallbackPoint::PostEnd }
|
||||
};
|
||||
|
||||
static const std::unordered_map<std::string, VolumeEventType> EVENT_TYPES
|
||||
{
|
||||
{ ScriptReserved_OnEnter, VolumeEventType::Enter },
|
||||
{ ScriptReserved_OnInside, VolumeEventType::Inside },
|
||||
{ ScriptReserved_OnLeave, VolumeEventType::Leave }
|
||||
};
|
||||
|
||||
enum class LevelEndReason
|
||||
{
|
||||
LevelComplete,
|
||||
|
@ -60,7 +68,7 @@ enum class LevelEndReason
|
|||
Other
|
||||
};
|
||||
|
||||
static const std::unordered_map<std::string, LevelEndReason> kLevelEndReasons
|
||||
static const std::unordered_map<std::string, LevelEndReason> LEVEL_END_REASONS
|
||||
{
|
||||
{ ScriptReserved_EndReasonLevelComplete, LevelEndReason::LevelComplete },
|
||||
{ ScriptReserved_EndReasonLoadGame, LevelEndReason::LoadGame },
|
||||
|
@ -154,9 +162,11 @@ LogicHandler::LogicHandler(sol::state* lua, sol::table & parent) : m_handler{ lu
|
|||
|
||||
tableLogic.set_function(ScriptReserved_AddCallback, &LogicHandler::AddCallback, this);
|
||||
tableLogic.set_function(ScriptReserved_RemoveCallback, &LogicHandler::RemoveCallback, this);
|
||||
tableLogic.set_function(ScriptReserved_HandleEvent, &LogicHandler::HandleEvent, this);
|
||||
|
||||
m_handler.MakeReadOnlyTable(tableLogic, ScriptReserved_EndReason, kLevelEndReasons);
|
||||
m_handler.MakeReadOnlyTable(tableLogic, ScriptReserved_CallbackPoint, kCallbackPoints);
|
||||
m_handler.MakeReadOnlyTable(tableLogic, ScriptReserved_EndReason, LEVEL_END_REASONS);
|
||||
m_handler.MakeReadOnlyTable(tableLogic, ScriptReserved_CallbackPoint, CALLBACK_POINTS);
|
||||
m_handler.MakeReadOnlyTable(tableLogic, ScriptReserved_EventType, EVENT_TYPES);
|
||||
|
||||
m_callbacks.insert(std::make_pair(CallbackPoint::PreStart, &m_callbacksPreStart));
|
||||
m_callbacks.insert(std::make_pair(CallbackPoint::PostStart, &m_callbacksPostStart));
|
||||
|
@ -260,6 +270,24 @@ void LogicHandler::RemoveCallback(CallbackPoint point, const LevelFunc& levelFun
|
|||
it->second->erase(levelFunc.m_funcName);
|
||||
}
|
||||
|
||||
/*** Attempt to find an event set and exectute a particular event from it.
|
||||
|
||||
@function HandleEvent
|
||||
@tparam name string Name of the event set to find.
|
||||
@tparam type EventType Event to execute.
|
||||
@tparam activator Moveable Optional activator. Default is the player object.
|
||||
*/
|
||||
void LogicHandler::HandleEvent(const std::string& name, VolumeEventType type, sol::optional<Moveable&> activator)
|
||||
{
|
||||
bool success = TEN::Control::Volumes::HandleEvent(name, type, activator.has_value() ?
|
||||
(VolumeActivator)activator.value().GetIndex() : nullptr);
|
||||
if (!success)
|
||||
{
|
||||
TENLog("Error: event " + name + " could not be executed. Check if event with such name exists in project.",
|
||||
LogLevel::Error, LogConfig::All, false);
|
||||
}
|
||||
}
|
||||
|
||||
void LogicHandler::ResetLevelTables()
|
||||
{
|
||||
auto state = m_handler.GetState();
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
#include "Game/items.h"
|
||||
#include "Scripting/Include/ScriptInterfaceGame.h"
|
||||
#include "Scripting/Internal/LuaHandler.h"
|
||||
#include "Scripting/Internal/ScriptUtil.h"
|
||||
#include "Scripting/Internal/TEN/Objects/Moveable/MoveableObject.h"
|
||||
|
||||
enum class CallbackPoint;
|
||||
class LevelFunc;
|
||||
|
@ -121,6 +123,7 @@ public:
|
|||
|
||||
void AddCallback(CallbackPoint point, const LevelFunc& levelFunc);
|
||||
void RemoveCallback(CallbackPoint point, const LevelFunc& levelFunc);
|
||||
void HandleEvent(const std::string& name, VolumeEventType type, sol::optional<Moveable&> activator);
|
||||
|
||||
void ResetScripts(bool clearGameVars) override;
|
||||
void ShortenTENCalls() override;
|
||||
|
|
|
@ -310,11 +310,12 @@ namespace Misc
|
|||
return (int)round(Vector3::Distance(p1, p2));
|
||||
}
|
||||
|
||||
// TODO: Deprecated. Also should not use int!
|
||||
///Calculate the horizontal distance between two positions.
|
||||
//@function CalculateHorizontalDistance
|
||||
//@tparam Vec3 posA first position
|
||||
//@tparam Vec3 posB second position
|
||||
//@treturn int the direct distance on the XZ plane from one position to the other
|
||||
//@treturn float the direct distance on the XZ plane from one position to the other
|
||||
static int CalculateHorizontalDistance(const Vec3& pos1, const Vec3& pos2)
|
||||
{
|
||||
auto p1 = Vector2(pos1.x, pos1.z);
|
||||
|
@ -322,49 +323,49 @@ namespace Misc
|
|||
return (int)round(Vector2::Distance(p1, p2));
|
||||
}
|
||||
|
||||
///Translate a pair of percentages to screen-space pixel coordinates.
|
||||
//To be used with @{Strings.DisplayString:SetPosition} and @{Strings.DisplayString}.
|
||||
/// Translate a pair display position coordinates to pixel coordinates.
|
||||
//To be used with @{ Strings.DisplayString:SetPosition } and @{ Strings.DisplayString }.
|
||||
//@function PercentToScreen
|
||||
//@tparam float x percent value to translate to x-coordinate
|
||||
//@tparam float y percent value to translate to y-coordinate
|
||||
//@treturn int x coordinate in pixels
|
||||
//@treturn int y coordinate in pixels
|
||||
//@tparam float x X component of the display position.
|
||||
//@tparam float y Y component of the display position.
|
||||
//@treturn int x X coordinate in pixels.
|
||||
//@treturn int y Y coordinate in pixels.
|
||||
//@usage
|
||||
//local halfwayX, halfwayY = PercentToScreen(50, 50)
|
||||
//local baddy
|
||||
//local spawnLocationNullmesh = GetMoveableByName("position_behind_left_pillar")
|
||||
//local str1 = DisplayString("You spawned a baddy!", halfwayX, halfwayY, Color(255, 100, 100), false, {DisplayStringOption.SHADOW, DisplayStringOption.CENTER})
|
||||
//local str1 = DisplayString("You spawned an enemy!", halfwayX, halfwayY, Color(255, 100, 100), false, { DisplayStringOption.SHADOW, DisplayStringOption.CENTER })
|
||||
//
|
||||
//LevelFuncs.triggerOne = function(obj)
|
||||
// ShowString(str1, 4)
|
||||
//end
|
||||
static std::tuple<int, int> PercentToScreen(double x, double y)
|
||||
static std::tuple<int, int> PercentToScreen(float x, float y)
|
||||
{
|
||||
auto fWidth = (double)g_Configuration.ScreenWidth;
|
||||
auto fHeight = (double)g_Configuration.ScreenHeight;
|
||||
int resX = (int)std::round(fWidth / 100.0 * x);
|
||||
int resY = (int)std::round(fHeight / 100.0 * y);
|
||||
//todo this still assumes a resolution of 800/600. account for this somehow
|
||||
float fWidth = g_Configuration.ScreenWidth;
|
||||
float fHeight = g_Configuration.ScreenHeight;
|
||||
int resX = (int)std::round(fWidth / 100.0f * x);
|
||||
int resY = (int)std::round(fHeight / 100.0f * y);
|
||||
|
||||
return std::make_tuple(resX, resY);
|
||||
}
|
||||
|
||||
/// Translate a pair of coordinates to percentages of window dimensions.
|
||||
/// Translate a pair of pixel coordinates to display position coordinates.
|
||||
//To be used with @{ Strings.DisplayString:GetPosition }.
|
||||
//@function ScreenToPercent
|
||||
//@tparam int x pixel value to translate to a percentage of the window width
|
||||
//@tparam int y pixel value to translate to a percentage of the window height
|
||||
//@treturn float x coordinate as percentage
|
||||
//@treturn float y coordinate as percentage
|
||||
static std::tuple<double, double> ScreenToPercent(int x, int y)
|
||||
//@tparam int x X pixel coordinate to translate to display position.
|
||||
//@tparam int y Y pixel coordinate to translate to display position.
|
||||
//@treturn float x X component of display position.
|
||||
//@treturn float y Y component of display position.
|
||||
static std::tuple<float, float> ScreenToPercent(int x, int y)
|
||||
{
|
||||
auto fWidth = (double)g_Configuration.ScreenWidth;
|
||||
auto fHeight = (double)g_Configuration.ScreenHeight;
|
||||
double resX = x / fWidth * 100.0;
|
||||
double resY = y / fHeight * 100.0;
|
||||
float fWidth = g_Configuration.ScreenWidth;
|
||||
float fHeight = g_Configuration.ScreenHeight;
|
||||
float resX = x / fWidth * 100.0f;
|
||||
float resY = y / fHeight * 100.0f;
|
||||
return std::make_tuple(resX, resY);
|
||||
}
|
||||
|
||||
/// Reset object camera back to Lara and deactivate object camera.
|
||||
/// Reset object camera back to the player and deactivate object camera.
|
||||
//@function ResetObjCamera
|
||||
static void ResetObjCamera()
|
||||
{
|
||||
|
@ -457,6 +458,7 @@ namespace Misc
|
|||
tableMisc.set_function(ScriptReserved_FlipMap, &FlipMap);
|
||||
tableMisc.set_function(ScriptReserved_PlayFlyBy, &PlayFlyBy);
|
||||
tableMisc.set_function(ScriptReserved_ResetObjCamera, &ResetObjCamera);
|
||||
|
||||
tableMisc.set_function(ScriptReserved_PrintLog, &PrintLog);
|
||||
|
||||
LuaHandler handler{ state };
|
||||
|
|
|
@ -19,7 +19,7 @@ static auto newindex_error = newindex_error_maker(AIObject, ScriptReserved_AIObj
|
|||
AIObject::AIObject(AI_OBJECT & ref) : m_aiObject{ref}
|
||||
{};
|
||||
|
||||
void AIObject::Register(sol::table & parent)
|
||||
void AIObject::Register(sol::table& parent)
|
||||
{
|
||||
parent.new_usertype<AIObject>(ScriptReserved_AIObject,
|
||||
sol::no_constructor, // ability to spawn new ones could be added later
|
||||
|
|
|
@ -20,7 +20,7 @@ public:
|
|||
AIObject& operator=(AIObject const& other) = delete;
|
||||
AIObject(AIObject const& other) = delete;
|
||||
|
||||
static void Register(sol::table & parent);
|
||||
static void Register(sol::table& parent);
|
||||
|
||||
Vec3 GetPos() const;
|
||||
void SetPos(Vec3 const& pos);
|
||||
|
|
|
@ -22,7 +22,7 @@ static auto newindex_error = newindex_error_maker(CameraObject, ScriptReserved_C
|
|||
CameraObject::CameraObject(LevelCameraInfo & ref) : m_camera{ref}
|
||||
{};
|
||||
|
||||
void CameraObject::Register(sol::table & parent)
|
||||
void CameraObject::Register(sol::table& parent)
|
||||
{
|
||||
parent.new_usertype<CameraObject>(ScriptReserved_Camera,
|
||||
sol::no_constructor, // ability to spawn new ones could be added later
|
||||
|
|
|
@ -22,7 +22,7 @@ public:
|
|||
CameraObject& operator=(CameraObject const& other) = delete;
|
||||
CameraObject(CameraObject const& other) = delete;
|
||||
|
||||
static void Register(sol::table &);
|
||||
static void Register(sol::table&);
|
||||
Vec3 GetPos() const;
|
||||
void SetPos(Vec3 const& pos);
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ public:
|
|||
void UndrawWeapon();
|
||||
void ThrowAwayTorch();
|
||||
bool TorchIsLit() const;
|
||||
static void Register(sol::table & parent);
|
||||
static void Register(sol::table& parent);
|
||||
using Moveable::Moveable;
|
||||
};
|
||||
|
||||
|
|
|
@ -76,19 +76,18 @@ most can just be ignored (see usage).
|
|||
@tparam string name Lua name of the item
|
||||
@tparam Vec3 position position in level
|
||||
@tparam[opt] Rotation rotation rotation about x, y, and z axes (default Rotation(0, 0, 0))
|
||||
@int[opt] room room ID item is in (default: calculated automatically)
|
||||
@int[opt] roomID room ID item is in (default: calculated automatically)
|
||||
@int[opt=0] animNumber anim number
|
||||
@int[opt=0] frameNumber frame number
|
||||
@int[opt=10] hp HP of item
|
||||
@int[opt=0] OCB ocb of item (default 0)
|
||||
@tparam[opt] table AIBits table with AI bits (default {0,0,0,0,0,0})
|
||||
@tparam[opt] table AIBits table with AI bits (default { 0, 0, 0, 0, 0, 0 })
|
||||
@treturn Moveable A new Moveable object (a wrapper around the new object)
|
||||
@usage
|
||||
local item = Moveable(
|
||||
TEN.Objects.ObjID.PISTOLS_ITEM, -- object id
|
||||
"test", -- name
|
||||
Vec3(18907, 0, 21201)
|
||||
)
|
||||
Vec3(18907, 0, 21201))
|
||||
*/
|
||||
static std::unique_ptr<Moveable> Create(
|
||||
GAME_OBJECT_ID objID,
|
||||
|
|
|
@ -19,13 +19,13 @@ when you need to use screen-space coordinates.
|
|||
@pragma nostrip
|
||||
*/
|
||||
|
||||
UserDisplayString::UserDisplayString(const std::string& key, int x, int y, D3DCOLOR color, const FlagArray& flags, bool translated) :
|
||||
m_key{ key },
|
||||
m_x{ x },
|
||||
m_y{ y },
|
||||
m_color{ color },
|
||||
m_flags{ flags },
|
||||
m_isTranslated{ translated }
|
||||
UserDisplayString::UserDisplayString(const std::string& key, int x, int y, D3DCOLOR color, const FlagArray& flags, bool isTranslated) :
|
||||
m_key(key),
|
||||
m_x(x),
|
||||
m_y(y),
|
||||
m_color(color),
|
||||
m_flags(flags),
|
||||
m_isTranslated(isTranslated)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -38,18 +38,19 @@ DisplayString::DisplayString()
|
|||
}
|
||||
|
||||
/*** Create a DisplayString.
|
||||
For use in @{Strings.ShowString|ShowString} and @{Strings.HideString|HideString}.
|
||||
For use in @{ Strings.ShowString | ShowString } and @{ Strings.HideString | HideString }.
|
||||
@function DisplayString
|
||||
@tparam string str string to print or key of translated string
|
||||
@tparam int x x-coordinate of top-left of string (or the center if DisplayStringOption.CENTER is given)
|
||||
@tparam int y y-coordinate of top-left of string (or the center if DisplayStringOption.CENTER is given)
|
||||
@tparam Color color the color of the text
|
||||
@tparam bool translated if false or omitted, the str argument will be printed.
|
||||
If true, the str argument will be the key of a translated string specified in
|
||||
strings.lua. __Default: false__.
|
||||
@tparam table flags a table of display options. Can be empty or omitted. The possible values and their effects are...
|
||||
TEN.Strings.DisplayStringOption.CENTER -- see x and y parameters
|
||||
TEN.Strings.DisplayStringOption.SHADOW -- will give the text a small shadow
|
||||
@tparam string string The string to display or key of the translated string.
|
||||
@tparam int x X component of the string.
|
||||
@tparam int y Y component of the string.
|
||||
@tparam Color color The color of the string.
|
||||
@tparam bool[opt] translated If false or omitted, the input string argument will be displayed.
|
||||
If true, the string argument will be the key of a translated string specified in strings.lua. __Default: false__.
|
||||
@tparam table[opt] flags A table of string display options. Can be empty or omitted. The possible values and their effects are:
|
||||
TEN.Strings.DisplayStringOption.CENTER: set the horizontal origin point to the center of the string.
|
||||
TEN.Strings.DisplayStringOption.RIGHT: set the horizontal origin point to right of the string.
|
||||
TEN.Strings.DisplayStringOption.SHADOW: give the string a small shadow.
|
||||
TEN.Strings.DisplayStringOption.BLINK: blink the string.
|
||||
__Default: empty__
|
||||
@treturn DisplayString A new DisplayString object.
|
||||
*/
|
||||
|
@ -103,21 +104,21 @@ void DisplayString::Register(sol::table& parent)
|
|||
/// Get the display string's color
|
||||
// @function DisplayString:GetColor
|
||||
// @treturn Color a copy of the display string's color
|
||||
ScriptReserved_GetColor, &DisplayString::GetCol,
|
||||
ScriptReserved_GetColor, &DisplayString::GetColor,
|
||||
|
||||
/// Set the display string's color
|
||||
// @function DisplayString:SetColor
|
||||
// @tparam Color color the new color of the display string
|
||||
ScriptReserved_SetColor, &DisplayString::SetCol,
|
||||
ScriptReserved_SetColor, &DisplayString::SetColor,
|
||||
|
||||
/// Get the string key to use. If `translated` is true when @{DisplayString}
|
||||
/// Get the string key to use. If `isTranslated` is true when @{ DisplayString }
|
||||
// is called, this will be the string key for the translation that will be displayed.
|
||||
// If false or omitted, this will be the string that's displayed.
|
||||
// @function DisplayString:GetKey
|
||||
// @treturn string a string
|
||||
ScriptReserved_GetKey, &DisplayString::GetKey,
|
||||
|
||||
/// Set the string key to use. If `translated` is true when @{DisplayString}
|
||||
/// Set the string key to use. If `isTranslated` is true when @{ DisplayString }
|
||||
// is called, this will be the string key for the translation that will be displayed.
|
||||
// If false or omitted, this will be the string that's displayed.
|
||||
// @function DisplayString:SetKey
|
||||
|
@ -128,15 +129,15 @@ void DisplayString::Register(sol::table& parent)
|
|||
/// Set the position of the string.
|
||||
// Screen-space coordinates are expected.
|
||||
// @function DisplayString:SetPosition
|
||||
// @tparam int x x-coordinate of the string
|
||||
// @tparam int y y-coordinate of the string
|
||||
// @tparam int x X component.
|
||||
// @tparam int y Y component.
|
||||
ScriptReserved_SetPosition, &DisplayString::SetPos,
|
||||
|
||||
/// Get the position of the string.
|
||||
// Screen-space coordinates are returned.
|
||||
// @function DisplayString:GetPosition
|
||||
// @treturn int x x-coordinate of the string
|
||||
// @treturn int y y-coordinate of the string
|
||||
// @treturn int x X component.
|
||||
// @treturn int y Y component.
|
||||
ScriptReserved_GetPosition, &DisplayString::GetPos,
|
||||
|
||||
/// Set the display string's flags
|
||||
|
@ -157,8 +158,7 @@ void DisplayString::Register(sol::table& parent)
|
|||
// @function DisplayString:SetTranslated
|
||||
// @tparam bool shouldTranslate if true, the string's key will be used as the key for the translation that will be displayed.
|
||||
// If false, the key itself will be displayed
|
||||
ScriptReserved_SetTranslated, &DisplayString::SetTranslated
|
||||
);
|
||||
ScriptReserved_SetTranslated, &DisplayString::SetTranslated);
|
||||
}
|
||||
|
||||
DisplayStringIDType DisplayString::GetID() const
|
||||
|
@ -179,7 +179,7 @@ std::tuple<int, int> DisplayString::GetPos() const
|
|||
return std::make_tuple(displayString.m_x, displayString.m_y);
|
||||
}
|
||||
|
||||
void DisplayString::SetCol(const ScriptColor& color)
|
||||
void DisplayString::SetColor(const ScriptColor& color)
|
||||
{
|
||||
UserDisplayString& displayString = s_getItemCallback(m_id).value();
|
||||
displayString.m_color = color;
|
||||
|
@ -188,10 +188,10 @@ void DisplayString::SetCol(const ScriptColor& color)
|
|||
//s_addItemCallback(m_id, s);
|
||||
}
|
||||
|
||||
ScriptColor DisplayString::GetCol()
|
||||
ScriptColor DisplayString::GetColor()
|
||||
{
|
||||
UserDisplayString& s = s_getItemCallback(m_id).value();
|
||||
return s.m_color;
|
||||
UserDisplayString& displayString = s_getItemCallback(m_id).value();
|
||||
return displayString.m_color;
|
||||
}
|
||||
|
||||
void DisplayString::SetKey(const std::string& key)
|
||||
|
|
|
@ -4,20 +4,25 @@
|
|||
|
||||
#include "Scripting/Internal/TEN/Color/Color.h"
|
||||
|
||||
enum class DisplayStringOptions : size_t
|
||||
enum class DisplayStringOptions
|
||||
{
|
||||
CENTER,
|
||||
OUTLINE,
|
||||
NUM_OPTIONS
|
||||
Center,
|
||||
Outline,
|
||||
Right,
|
||||
Blink,
|
||||
|
||||
Count
|
||||
};
|
||||
|
||||
static const std::unordered_map<std::string, DisplayStringOptions> kDisplayStringOptionNames
|
||||
static const std::unordered_map<std::string, DisplayStringOptions> DISPLAY_STRING_OPTION_NAMES
|
||||
{
|
||||
{"CENTER", DisplayStringOptions::CENTER},
|
||||
{"SHADOW", DisplayStringOptions::OUTLINE}
|
||||
{ "CENTER", DisplayStringOptions::Center },
|
||||
{ "SHADOW", DisplayStringOptions::Outline },
|
||||
{ "RIGHT", DisplayStringOptions::Right },
|
||||
{ "BLINK", DisplayStringOptions::Blink }
|
||||
};
|
||||
|
||||
using FlagArray = std::array<bool, static_cast<size_t>(DisplayStringOptions::NUM_OPTIONS)>;
|
||||
using FlagArray = std::array<bool, (int)DisplayStringOptions::Count>;
|
||||
// Used to store data used to render the string.
|
||||
// This is separate from DisplayString because the lifetimes of the classes differ slightly.
|
||||
|
||||
|
@ -62,8 +67,8 @@ public:
|
|||
void SetPos(int x, int y);
|
||||
std::tuple<int, int> GetPos() const;
|
||||
|
||||
void SetCol(const ScriptColor&);
|
||||
ScriptColor GetCol();
|
||||
void SetColor(const ScriptColor&);
|
||||
ScriptColor GetColor();
|
||||
|
||||
void SetKey(const std::string&);
|
||||
std::string GetKey() const;
|
||||
|
|
|
@ -12,7 +12,8 @@ On-screen strings.
|
|||
@pragma nostrip
|
||||
*/
|
||||
|
||||
StringsHandler::StringsHandler(sol::state* lua, sol::table & parent) : LuaHandler{ lua }
|
||||
StringsHandler::StringsHandler(sol::state* lua, sol::table& parent) :
|
||||
LuaHandler{ lua }
|
||||
{
|
||||
sol::table table_strings{ m_lua->lua_state(), sol::create };
|
||||
parent.set(ScriptReserved_Strings, table_strings);
|
||||
|
@ -46,12 +47,11 @@ Checks if the string is shown
|
|||
|
||||
DisplayString::Register(table_strings);
|
||||
DisplayString::SetCallbacks(
|
||||
[this](auto && ... param) {return SetDisplayString(std::forward<decltype(param)>(param)...); },
|
||||
[this](auto && ... param) {return ScheduleRemoveDisplayString(std::forward<decltype(param)>(param)...); },
|
||||
[this](auto && ... param) {return GetDisplayString(std::forward<decltype(param)>(param)...); }
|
||||
);
|
||||
[this](auto && ... param) { return SetDisplayString(std::forward<decltype(param)>(param)...); },
|
||||
[this](auto && ... param) { return ScheduleRemoveDisplayString(std::forward<decltype(param)>(param)...); },
|
||||
[this](auto && ... param) { return GetDisplayString(std::forward<decltype(param)>(param)...); });
|
||||
|
||||
MakeReadOnlyTable(table_strings, ScriptReserved_DisplayStringOption, kDisplayStringOptionNames);
|
||||
MakeReadOnlyTable(table_strings, ScriptReserved_DisplayStringOption, DISPLAY_STRING_OPTION_NAMES);
|
||||
}
|
||||
|
||||
std::optional<std::reference_wrapper<UserDisplayString>> StringsHandler::GetDisplayString(DisplayStringIDType id)
|
||||
|
@ -116,12 +116,18 @@ void StringsHandler::ProcessDisplayStrings(float deltaTime)
|
|||
auto cstr = str.m_isTranslated ? g_GameFlow->GetString(str.m_key.c_str()) : str.m_key.c_str();
|
||||
int flags = 0;
|
||||
|
||||
if (str.m_flags[static_cast<size_t>(DisplayStringOptions::CENTER)])
|
||||
if (str.m_flags[(size_t)DisplayStringOptions::Center])
|
||||
flags |= PRINTSTRING_CENTER;
|
||||
|
||||
if (str.m_flags[static_cast<size_t>(DisplayStringOptions::OUTLINE)])
|
||||
if (str.m_flags[(size_t)DisplayStringOptions::Right])
|
||||
flags |= PRINTSTRING_RIGHT;
|
||||
|
||||
if (str.m_flags[(size_t)DisplayStringOptions::Outline])
|
||||
flags |= PRINTSTRING_OUTLINE;
|
||||
|
||||
if (str.m_flags[(size_t)DisplayStringOptions::Blink])
|
||||
flags |= PRINTSTRING_BLINK;
|
||||
|
||||
m_callbackDrawSring(cstr, str.m_color, str.m_x, str.m_y, flags);
|
||||
|
||||
str.m_timeRemaining -= deltaTime;
|
||||
|
|
|
@ -1001,9 +1001,8 @@ void LoadEventSets()
|
|||
eventSet.Name = ReadString();
|
||||
eventSet.Activators = (VolumeActivatorFlags)ReadInt32();
|
||||
|
||||
LoadEvent(eventSet.OnEnter);
|
||||
LoadEvent(eventSet.OnInside);
|
||||
LoadEvent(eventSet.OnLeave);
|
||||
for (int eventType = 0; eventType < (int)VolumeEventType::Count; eventType++)
|
||||
LoadEvent(eventSet.Events[eventType]);
|
||||
|
||||
g_Level.EventSets.push_back(eventSet);
|
||||
}
|
||||
|
|
|
@ -713,6 +713,9 @@ xcopy /Y "$(SolutionDir)Libs\zlib\x64\*.dll" "$(TargetDir)"</Command>
|
|||
<ClInclude Include="Scripting\Internal\ScriptAssert.h" />
|
||||
<ClInclude Include="Scripting\Internal\ScriptUtil.h" />
|
||||
<ClInclude Include="Scripting\Internal\TEN\Color\Color.h" />
|
||||
<ClInclude Include="Scripting\Internal\TEN\DisplaySprite\AlignModes.h" />
|
||||
<ClInclude Include="Scripting\Internal\TEN\DisplaySprite\ScaleModes.h" />
|
||||
<ClInclude Include="Scripting\Internal\TEN\DisplaySprite\ScriptDisplaySprite.h" />
|
||||
<ClInclude Include="Scripting\Internal\TEN\Effects\BlendIDs.h" />
|
||||
<ClInclude Include="Scripting\Internal\TEN\Effects\EffectIDs.h" />
|
||||
<ClInclude Include="Scripting\Internal\TEN\Effects\EffectsFunctions.h" />
|
||||
|
@ -1132,6 +1135,7 @@ xcopy /Y "$(SolutionDir)Libs\zlib\x64\*.dll" "$(TargetDir)"</Command>
|
|||
<ClCompile Include="Scripting\Internal\ScriptInterfaceState.cpp" />
|
||||
<ClCompile Include="Scripting\Internal\ScriptUtil.cpp" />
|
||||
<ClCompile Include="Scripting\Internal\TEN\Color\Color.cpp" />
|
||||
<ClCompile Include="Scripting\Internal\TEN\DisplaySprite\ScriptDisplaySprite.cpp" />
|
||||
<ClCompile Include="Scripting\Internal\TEN\Effects\EffectsFunctions.cpp" />
|
||||
<ClCompile Include="Scripting\Internal\TEN\Flow\Animations\Animations.cpp" />
|
||||
<ClCompile Include="Scripting\Internal\TEN\Flow\FlowHandler.cpp" />
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue