TombEngine/TombEngine/Scripting/Internal/TEN/DisplaySprite/ScriptDisplaySprite.cpp

230 lines
9.1 KiB
C++
Raw Normal View History

2023-09-30 16:54:57 +10:00
#include "framework.h"
2023-10-06 14:10:37 +11:00
#include "Scripting/Internal/TEN/DisplaySprite/ScriptDisplaySprite.h"
2023-09-30 16:54:57 +10:00
#include "Game/effects/DisplaySprite.h"
#include "Game/Setup.h"
#include "Objects/game_object_ids.h"
2023-10-11 18:23:38 +11:00
#include "Renderer/Renderer11.h"
2023-09-30 16:54:57 +10:00
#include "Scripting/Internal/LuaHandler.h"
#include "Scripting/Internal/ReservedScriptNames.h"
#include "Scripting/Internal/TEN/Color/Color.h"
2023-10-06 14:10:37 +11:00
#include "Scripting/Internal/TEN/DisplaySprite/AlignModes.h"
#include "Scripting/Internal/TEN/DisplaySprite/ScaleModes.h"
2023-09-30 16:54:57 +10:00
#include "Scripting/Internal/TEN/Vec2/Vec2.h"
using namespace TEN::Effects::DisplaySprite;
2023-10-11 18:23:38 +11:00
using TEN::Renderer::g_Renderer;
2023-09-30 16:54:57 +10:00
namespace TEN::Scripting::DisplaySprite
2023-09-30 16:54:57 +10:00
{
2023-10-08 15:25:28 +11:00
void ScriptDisplaySprite::Register(sol::state& state, sol::table& parent)
{
2023-10-19 16:23:34 +11:00
// NOTE: Single constructor with a sol::optional argument for the color doesn't work, hence the two constructors. -- Sezz 2023.10.19
using ctors = sol::constructors<
ScriptDisplaySprite(GAME_OBJECT_ID, int, const Vec2&, float, const Vec2&, const ScriptColor&),
ScriptDisplaySprite(GAME_OBJECT_ID, int, const Vec2&, float, const Vec2&)>;
2023-09-30 16:54:57 +10:00
2023-10-09 12:20:35 +11:00
// Register type.
parent.new_usertype<ScriptDisplaySprite>(
ScriptReserved_DisplaySprite,
ctors(),
sol::call_constructor, ctors(),
2023-09-30 16:54:57 +10:00
2023-10-09 12:03:22 +11:00
ScriptReserved_DisplayStringGetObjectID, &ScriptDisplaySprite::GetObjectID,
ScriptReserved_DisplayStringGetSpriteID, &ScriptDisplaySprite::GetSpriteID,
ScriptReserved_DisplayStringGetPosition, &ScriptDisplaySprite::GetPosition,
ScriptReserved_DisplayStringGetRotation, &ScriptDisplaySprite::GetRotation,
2023-10-09 12:03:22 +11:00
ScriptReserved_DisplayStringGetScale, &ScriptDisplaySprite::GetScale,
ScriptReserved_DisplayStringGetColor, &ScriptDisplaySprite::GetColor,
2023-10-09 12:03:22 +11:00
ScriptReserved_DisplayStringSetObjectID, &ScriptDisplaySprite::SetObjectID,
ScriptReserved_DisplayStringSetSpriteID, &ScriptDisplaySprite::SetSpriteID,
ScriptReserved_DisplayStringSetPosition, &ScriptDisplaySprite::SetPosition,
ScriptReserved_DisplayStringSetRotation, &ScriptDisplaySprite::SetRotation,
ScriptReserved_DisplayStringSetScale, &ScriptDisplaySprite::SetScale,
ScriptReserved_DisplayStringSetColor, &ScriptDisplaySprite::SetColor,
ScriptReserved_DisplaySpriteDraw, &ScriptDisplaySprite::Draw);
2023-10-08 15:25:28 +11:00
auto table = sol::table(state.lua_state(), sol::create);
2023-10-09 12:03:22 +11:00
parent.set(ScriptReserved_DisplaySpriteEnum, table);
2023-10-08 15:25:28 +11:00
2023-10-09 12:20:35 +11:00
// Register enums.
2023-10-08 15:25:28 +11:00
auto handler = LuaHandler(&state);
2023-10-09 12:03:22 +11:00
handler.MakeReadOnlyTable(table, ScriptReserved_DisplaySpriteEnumAlignMode, DISPLAY_SPRITE_ALIGN_MODES);
handler.MakeReadOnlyTable(table, ScriptReserved_DisplaySpriteEnumScaleMode, DISPLAY_SPRITE_SCALE_MODES);
}
/// Create a DisplaySprite object.
2023-10-19 15:52:14 +11:00
// @function DisplaySprite
// @tparam Objects.ObjID ID of the sprite sequence object.
// @tparam int int spriteID ID of the sprite in the sequence.
// @tparam Vec2 pos Display position in percent.
// @tparam float rot Rotation in degrees.
// @tparam Vec2 scale Horizontal and vertical scale in percent. Scaling is interpreted by the DisplaySpriteEnum.ScaleMode passed to the Draw() function call.
// @tparam Color color[opt] Color. __Default: Color(255, 255, 255, 255)__
// @treturn DisplaySprite A new DisplaySprite object.
ScriptDisplaySprite::ScriptDisplaySprite(GAME_OBJECT_ID objectID, int spriteID, const Vec2& pos, float rot, const Vec2& scale, const ScriptColor& color)
2023-09-30 16:54:57 +10:00
{
2023-10-28 16:27:43 +11:00
_objectID = objectID;
_spriteID = spriteID;
_position = pos;
_rotation = rot;
_scale = scale;
_color = color;
}
ScriptDisplaySprite::ScriptDisplaySprite(GAME_OBJECT_ID objectID, int spriteID, const Vec2& pos, float rot, const Vec2& scale)
{
static const auto DEFAULT_COLOR = ScriptColor(255, 255, 255, 255);
*this = ScriptDisplaySprite(objectID, spriteID, pos, rot, scale, DEFAULT_COLOR);
2023-09-30 16:54:57 +10:00
}
2023-10-19 15:52:14 +11:00
/// Get the object ID of the sprite sequence object used by the display sprite.
// @function DisplaySprite:GetObjectID()
// @treturn Objects.ObjID Sprite sequence object ID.
GAME_OBJECT_ID ScriptDisplaySprite::GetObjectID() const
{
2023-10-28 16:27:43 +11:00
return _objectID;
}
2023-10-19 15:52:14 +11:00
/// Get the sprite ID in the sprite sequence object used by the display sprite.
// @function DisplaySprite:GetSpriteID()
// @treturn int Sprite ID in the sprite sequence object.
int ScriptDisplaySprite::GetSpriteID() const
{
2023-10-28 16:27:43 +11:00
return _spriteID;
}
2023-10-19 15:52:14 +11:00
/// Get the display position of the display sprite in percent.
// @function DisplaySprite:GetPosition()
// @treturn Vec2 Display position in percent.
Vec2 ScriptDisplaySprite::GetPosition() const
{
2023-10-28 16:27:43 +11:00
return _position;
}
2023-10-19 15:52:14 +11:00
/// Get the rotation of the display sprite in degrees.
// @function DisplaySprite:GetRotation()
// @treturn float Rotation in degrees.
float ScriptDisplaySprite::GetRotation() const
{
2023-10-28 16:27:43 +11:00
return _rotation;
}
2023-10-19 15:52:14 +11:00
/// Get the horizontal and vertical scale of the display sprite in percent.
// @function DisplaySprite:GetScale()
// @treturn Vec2 Horizontal and vertical scale in percent.
Vec2 ScriptDisplaySprite::GetScale() const
{
2023-10-28 16:27:43 +11:00
return _scale;
}
2023-10-19 15:52:14 +11:00
/// Get the color of the display sprite.
// @function DisplaySprite:GetColor()
// @treturn Color Color.
ScriptColor ScriptDisplaySprite::GetColor() const
{
2023-10-28 16:27:43 +11:00
return _color;
}
2023-10-19 15:52:14 +11:00
/// Set the sprite sequence object ID used by the display sprite.
// @function DisplaySprite:SetObjectID(Objects.ObjID)
// @tparam Objects.ObjID New sprite sequence object ID.
void ScriptDisplaySprite::SetObjectID(GAME_OBJECT_ID objectID)
{
2023-10-28 16:27:43 +11:00
_objectID = objectID;
}
2023-10-19 15:52:14 +11:00
/// Set the sprite ID in the sprite sequence object used by the display sprite.
// @function DisplaySprite:SetSpriteID(int)
// @tparam int New sprite ID in the sprite sequence object.
void ScriptDisplaySprite::SetSpriteID(int spriteID)
{
2023-10-28 16:27:43 +11:00
_spriteID = spriteID;
}
2023-10-19 15:52:14 +11:00
/// Set the display position of the display sprite in percent.
// @function DisplaySprite:SetPosition(Vec2)
// @tparam Vec2 New display position in percent.
void ScriptDisplaySprite::SetPosition(const Vec2& pos)
{
2023-10-28 16:27:43 +11:00
_position = pos;
}
2023-10-19 15:52:14 +11:00
/// Set the rotation of the display sprite in degrees.
// @function DisplaySprite:SetRotation(float)
// @tparam float New rotation in degrees.
void ScriptDisplaySprite::SetRotation(float rot)
{
2023-10-28 16:27:43 +11:00
_rotation = rot;
}
2023-10-19 15:52:14 +11:00
/// Set the horizontal and vertical scale of the display sprite in percent.
// @function DisplaySprite:SetScale(Vec2)
// @tparam float New horizontal and vertical scale in percent.
void ScriptDisplaySprite::SetScale(const Vec2& scale)
{
2023-10-28 16:27:43 +11:00
_scale = scale;
}
2023-10-19 15:52:14 +11:00
/// Set the color of the display sprite.
// @function DisplaySprite:SetColor(Color)
// @tparam float New color.
void ScriptDisplaySprite::SetColor(const ScriptColor& color)
{
2023-10-28 16:27:43 +11:00
_color = color;
}
2023-10-19 15:52:14 +11:00
/// Draw the display sprite in display space for the current frame.
// @function DisplaySprite:Draw
// @tparam Objects.ObjID[opt] priority Draw priority. Can be thought of as a layer, with higher values having precedence. __Default: 0__
// @tparam DisplaySprite.AlignMode[opt] alignMode Align mode interpreting an offset from the sprite's position. __Default: DisplaySprite.AlignMode.CENTER__
// @tparam DisplaySprite.ScaleMode[opt] scaleMode Scale mode interpreting the display sprite's horizontal and vertical scale. __Default: DisplaySprite.ScaleMode.FIT__
// @tparam Effects.BlendID[opt] blendMode Blend mode. __Default: Effects.BlendID.ALPHABLEND__
void ScriptDisplaySprite::Draw(sol::optional<int> priority, sol::optional<DisplaySpriteAlignMode> alignMode,
2023-10-06 15:03:12 +11:00
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;
2023-10-06 15:03:12 +11:00
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;
2023-10-06 21:13:04 +11:00
// Object is not a sprite sequence object; return early.
2023-10-28 16:27:43 +11:00
if (_objectID < GAME_OBJECT_ID::ID_HORIZON || _objectID >= GAME_OBJECT_ID::ID_NUMBER_OBJECTS)
{
2023-10-28 16:27:43 +11:00
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.
2023-10-28 16:27:43 +11:00
const auto& object = Objects[_objectID];
if (!object.loaded || _spriteID >= abs(object.nmeshes))
{
TENLog(
2023-10-28 16:27:43 +11:00
"Attempted to draw missing sprite " + std::to_string(_spriteID) +
" from sprite sequence object " + std::to_string(_objectID) +
2023-10-06 15:05:28 +11:00
" as display sprite.",
LogLevel::Warning);
return;
}
2023-10-28 16:27:43 +11:00
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(
2023-10-28 16:27:43 +11:00
_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));
}
2023-09-30 16:54:57 +10:00
}