Start restructuring script Moveable class

This commit is contained in:
Sezz 2025-02-01 17:47:29 +11:00
parent 98b01ff64a
commit d8c646fabd
19 changed files with 1632 additions and 1733 deletions

File diff suppressed because it is too large Load diff

View file

@ -136,13 +136,13 @@
<p>Table of Objects.MoveableStatus constants. </p>
<p>To be used with <a href="../2 classes/Objects.Moveable.html#Moveable:GetStatus">Objects.Moveable.GetStatus</a> and <a href="../2 classes/Objects.Moveable.html#Moveable:SetStatus">Objects.Moveable.SetStatus</a> functions.</p>
<p> To be used with <a href="../2 classes/Objects.Moveable.html#Moveable:GetStatus">Objects.Moveable.GetStatus</a> and <a href="../2 classes/Objects.Moveable.html#Moveable:SetStatus">Objects.Moveable.SetStatus</a> functions.</p>
<ul>
<li><code>INACTIVE</code> - object was never activated.</li>
<li><code>ACTIVE</code> - object is active.</li>
<li><code>DEACTIVATED</code> - object was active before and was deactivated.</li>
<li><code>INVISIBLE</code> - object is invisible.</li>
<li><code>INACTIVE</code> - moveable is inactive (was never activated).</li>
<li><code>ACTIVE</code> - moveable is active.</li>
<li><code>DEACTIVATED</code> - moveable is deactivated (was previously active and later deactivated).</li>
<li><code>INVISIBLE</code> - moveable is invisible.</li>
</ul>

View file

@ -200,7 +200,7 @@ local door = GetMoveableByName("door_type4_14")
</tr>
<tr>
<td class="name" ><a href="2 classes/Objects.Moveable.html">Objects.Moveable</a></td>
<td class="summary">Represents a mopveable object in the game world.</td>
<td class="summary">Represents a moveable object in the game world.</td>
</tr>
<tr>
<td class="name" ><a href="2 classes/Objects.Room.html">Objects.Room</a></td>

View file

@ -9,6 +9,7 @@ struct AI_OBJECT;
struct ROOM_INFO;
using VarMapVal = std::variant<
int,
short,
std::reference_wrapper<MESH_INFO>,
std::reference_wrapper<LevelCameraInfo>,

View file

@ -323,7 +323,7 @@ Possible event type values:
*/
void LogicHandler::HandleEvent(const std::string& name, EventType type, sol::optional<Moveable&> activator)
{
TEN::Control::Volumes::HandleEvent(name, type, activator.has_value() ? (Activator)activator.value().GetIndex() : (Activator)short(LaraItem->Index));
TEN::Control::Volumes::HandleEvent(name, type, activator.has_value() ? (Activator)(short)activator->GetIndex() : (Activator)(short)LaraItem->Index);
}
/*** Attempt to find an event set and enable specified event in it.

View file

@ -132,17 +132,15 @@ std::string AIObject::GetName() const
return m_aiObject.Name;
}
void AIObject::SetName(std::string const & id)
void AIObject::SetName(const std::string& id)
{
if (!ScriptAssert(!id.empty(), "Name cannot be blank. Not setting name."))
{
return;
}
if (s_callbackSetName(id, m_aiObject))
if (_callbackSetName(id, m_aiObject))
{
// remove the old name if we have one
s_callbackRemoveName(m_aiObject.Name);
// Remove old name if it exists.
_callbackRemoveName(m_aiObject.Name);
m_aiObject.Name = id;
}
else

View file

@ -30,7 +30,7 @@ public:
void SetRoomNumber(short Room);
std::string GetName() const;
void SetName(std::string const &);
void SetName(const std::string&);
GAME_OBJECT_ID GetObjectID() const;
void SetObjectID(GAME_OBJECT_ID);

View file

@ -90,14 +90,12 @@ std::string CameraObject::GetName() const
void CameraObject::SetName(std::string const & id)
{
if (!ScriptAssert(!id.empty(), "Name cannot be blank. Not setting name."))
{
return;
}
if (s_callbackSetName(id, m_camera))
if (_callbackSetName(id, m_camera))
{
// remove the old name if we have one
s_callbackRemoveName(m_camera.Name);
// Remove old name if it exists.
_callbackRemoveName(m_camera.Name);
m_camera.Name = id;
}
else

View file

@ -32,7 +32,7 @@ using namespace TEN::Entities::Generic;
// Lara:SetPoison(10)
void LaraObject::SetPoison(sol::optional<int> potency)
{
auto* lara = GetLaraInfo(m_item);
auto* lara = GetLaraInfo(_moveable);
if (potency.has_value())
lara->Status.Poison = std::clamp(potency.value(), 0, (int)LARA_POISON_MAX);
@ -47,7 +47,7 @@ void LaraObject::SetPoison(sol::optional<int> potency)
// local poisonPotency = Lara:GetPoison()
int LaraObject::GetPoison() const
{
auto* lara = GetLaraInfo(m_item);
auto* lara = GetLaraInfo(_moveable);
return lara->Status.Poison;
}
@ -58,7 +58,7 @@ int LaraObject::GetPoison() const
// Lara:SetAir(100)
void LaraObject::SetAir(sol::optional<int> air)
{
auto* lara = GetLaraInfo(m_item);
auto* lara = GetLaraInfo(_moveable);
if (air.has_value())
lara->Status.Air = std::clamp(air.value(), 0, (int)LARA_AIR_MAX);
@ -73,7 +73,7 @@ void LaraObject::SetAir(sol::optional<int> air)
// local currentAir = Lara:GetAir()
int LaraObject::GetAir() const
{
auto* lara = GetLaraInfo(m_item);
auto* lara = GetLaraInfo(_moveable);
return lara->Status.Air;
}
@ -84,7 +84,7 @@ int LaraObject::GetAir() const
// Lara:SetWet(100)
void LaraObject::SetWet(sol::optional<int> wetness)
{
auto* lara = GetLaraInfo(m_item);
auto* lara = GetLaraInfo(_moveable);
float value = wetness.has_value() ? (float)wetness.value() : PLAYER_DRIP_NODE_MAX;
for (float& i : lara->Effect.DripNodes)
@ -98,7 +98,7 @@ void LaraObject::SetWet(sol::optional<int> wetness)
// local dripAmount = Lara:GetWet()
int LaraObject::GetWet() const
{
auto* lara = GetLaraInfo(m_item);
auto* lara = GetLaraInfo(_moveable);
return lara->Effect.DripNodes[0];
}
@ -109,7 +109,7 @@ int LaraObject::GetWet() const
// Lara:SetStamina(120)
void LaraObject::SetStamina(sol::optional<int> value)
{
auto* lara = GetLaraInfo(m_item);
auto* lara = GetLaraInfo(_moveable);
if (value.has_value())
lara->Status.Stamina = std::clamp(value.value(), 0, (int)LARA_STAMINA_MAX);
@ -124,7 +124,7 @@ void LaraObject::SetStamina(sol::optional<int> value)
// local sprintEnergy = Lara:GetStamina()
int LaraObject::GetStamina() const
{
auto* lara = GetLaraInfo(m_item);
auto* lara = GetLaraInfo(_moveable);
return lara->Status.Stamina;
}
@ -133,7 +133,7 @@ int LaraObject::GetStamina() const
// @treturn (bool) true if Lara state must react to aerial forces.
bool LaraObject::GetAirborne() const
{
return m_item->Animation.IsAirborne;
return _moveable->Animation.IsAirborne;
}
/// Set the moveable's airborne status
@ -141,7 +141,7 @@ bool LaraObject::GetAirborne() const
// @tparam (bool) New airborn status for Lara.
void LaraObject::SetAirborne(bool newAirborne)
{
m_item->Animation.IsAirborne = newAirborne;
_moveable->Animation.IsAirborne = newAirborne;
}
/// Lara will undraw her weapon if it is drawn and throw away a flare if she is currently holding one.
@ -150,7 +150,7 @@ void LaraObject::SetAirborne(bool newAirborne)
// Lara:UndrawWeapon()
void LaraObject::UndrawWeapon()
{
auto* lara = GetLaraInfo(m_item);
auto* lara = GetLaraInfo(_moveable);
if (lara->Control.HandStatus != HandStatus::Free ||
lara->Control.Weapon.GunType == LaraWeaponType::Flare)
@ -165,7 +165,7 @@ void LaraObject::UndrawWeapon()
// Lara:ThrowAwayTorch()
void LaraObject::ThrowAwayTorch()
{
auto* lara = GetLaraInfo(m_item);
auto* lara = GetLaraInfo(_moveable);
if (lara->Control.Weapon.GunType == LaraWeaponType::Torch)
{
@ -182,7 +182,7 @@ void LaraObject::ThrowAwayTorch()
// @treturn int hand status 0=HandsFree, 1=Busy(climbing,etc), 2=WeaponDraw, 3=WeaponUndraw, 4=WeaponInHand.
HandStatus LaraObject::GetHandStatus() const
{
auto* lara = GetLaraInfo(m_item);
auto* lara = GetLaraInfo(_moveable);
return HandStatus{ lara->Control.HandStatus };
}
@ -193,7 +193,7 @@ HandStatus LaraObject::GetHandStatus() const
// @treturn Flow.WeaponType current weapon type.
LaraWeaponType LaraObject::GetWeaponType() const
{
auto* lara = GetLaraInfo(m_item);
auto* lara = GetLaraInfo(_moveable);
return LaraWeaponType{ lara->Control.Weapon.GunType };
}
@ -205,7 +205,7 @@ LaraWeaponType LaraObject::GetWeaponType() const
// @tparam bool activate if `true`, also draw the weapons or set torch lit. If `false`, keep weapons holstered or leave torch unlit.
void LaraObject::SetWeaponType(LaraWeaponType weaponType, bool activate)
{
auto* lara = GetLaraInfo(m_item);
auto* lara = GetLaraInfo(_moveable);
switch (weaponType)
{
@ -235,7 +235,7 @@ void LaraObject::SetWeaponType(LaraWeaponType weaponType, bool activate)
// local CurrentAmmoType = Lara:GetAmmoType()
int LaraObject::GetAmmoType() const
{
const auto& player = GetLaraInfo(*m_item);
const auto& player = GetLaraInfo(*_moveable);
auto ammoType = std::optional<PlayerAmmoType>(std::nullopt);
switch (player.Control.Weapon.GunType)
@ -328,7 +328,7 @@ int LaraObject::GetAmmoType() const
// local equippedWeaponAmmoLeft = Lara:GetAmmoCount()
int LaraObject::GetAmmoCount() const
{
auto* lara = GetLaraInfo(m_item);
auto* lara = GetLaraInfo(_moveable);
auto& ammo = GetAmmo(Lara, Lara.Control.Weapon.GunType);
return (ammo.HasInfinite()) ? -1 : (int)ammo.GetCount();
}
@ -340,7 +340,7 @@ int LaraObject::GetAmmoCount() const
// local vehicle = Lara:GetVehicle()
std::unique_ptr<Moveable> LaraObject::GetVehicle() const
{
auto* lara = GetLaraInfo(m_item);
auto* lara = GetLaraInfo(_moveable);
if (lara->Context.Vehicle == NO_VALUE)
return nullptr;
@ -355,7 +355,7 @@ std::unique_ptr<Moveable> LaraObject::GetVehicle() const
// local target = Lara:GetTarget()
std::unique_ptr<Moveable> LaraObject::GetTarget() const
{
const auto& player = GetLaraInfo(*m_item);
const auto& player = GetLaraInfo(*_moveable);
if (player.TargetEntity == nullptr)
return nullptr;
@ -370,7 +370,7 @@ std::unique_ptr<Moveable> LaraObject::GetTarget() const
// local interactedMoveable = Lara:GetInteractedMoveable()
std::unique_ptr<Moveable> LaraObject::GetPlayerInteractedMoveable() const
{
const auto& player = GetLaraInfo(*m_item);
const auto& player = GetLaraInfo(*_moveable);
if (player.Context.InteractedItem == NO_VALUE)
return nullptr;
@ -385,7 +385,7 @@ std::unique_ptr<Moveable> LaraObject::GetPlayerInteractedMoveable() const
// local torchIsLit = Lara:TorchIsLit()
bool LaraObject::TorchIsLit() const
{
auto* lara = GetLaraInfo(m_item);
auto* lara = GetLaraInfo(_moveable);
return lara->Torch.IsLit;
}

View file

@ -4,17 +4,13 @@
#include "Scripting/Internal/TEN/Objects/NamedBase.h"
#include "Scripting/Internal/TEN/Objects/Room/RoomObject.h"
class LevelFunc;
namespace sol { class state; }
namespace sol { template <typename T> struct as_table_t; }
namespace sol
{
class state;
template <typename T> struct as_table_t;
}
enum ItemStatus;
enum GAME_OBJECT_ID : short;
enum ItemStatus;
enum class EffectType;
class LevelFunc;
class ScriptColor;
class Vec3;
struct ItemInfo;
@ -25,128 +21,117 @@ using namespace TEN::Scripting;
using aiBitsArray = std::array<int, 6>;
using aiBitsType = sol::as_table_t<aiBitsArray>;
class Moveable : public NamedBase<Moveable, short>
class Moveable : public NamedBase<Moveable, int>
{
public:
using IdentifierType = short;
static void Register(sol::state& state, sol::table& parent);
Moveable(short num, bool alreadyInitialized = true);
protected:
ItemInfo* _moveable = nullptr;
private:
int _moveableID = 0;
bool _initialized = false;
public:
using IdentifierType = int;
// Constructors, destructors
Moveable(int movID, bool alreadyInitialized = true);
Moveable(const Moveable& mov) = delete;
Moveable(Moveable&& mov) noexcept;
~Moveable();
Moveable& operator =(const Moveable& other) = delete;
Moveable(const Moveable& other) = delete;
Moveable(Moveable&& other) noexcept;
[[nodiscard]] GAME_OBJECT_ID GetObjectID() const;
void SetObjectID(GAME_OBJECT_ID id);
// Getters
[[nodiscard]] std::string GetName() const;
bool SetName(const std::string&);
[[nodiscard]] bool GetValid() const;
void Invalidate();
void Destroy();
Vec3 GetPos() const;
int GetIndex() const;
GAME_OBJECT_ID GetObjectID() const;
std::string GetName() const;
bool GetValid() const;
Vec3 GetPosition() const;
Vec3 GetJointPos(int jointID, sol::optional<Vec3> offset) const;
void SetPos(const Vec3& pos, sol::optional<bool> updateRoom);
Rotation GetJointRot(int index) const;
Rotation GetRotation() const;
int GetStateNumber() const;
int GetTargetStateNumber() const;
int GetAnimNumber() const;
int GetAnimSlot() const;
int GetFrameNumber() const;
int GetEndFrame() const;
Vec3 GetVelocity() const;
ScriptColor GetColor() const;
short GetHP() const;
short GetSlotHP() const;
short GetOcb() const;
EffectType GetEffect() const;
aiBitsType GetAIBits() const;
short GetItemFlags(int index = 0) const;
short GetLocationAI() const;
short GetMeshCount() const;
bool GetMeshVisible(int meshId) const;
bool GetMeshSwapped(int meshId) const;
bool GetHitStatus() const;
bool GetActive() const;
short GetStatus() const;
[[nodiscard]] Rotation GetJointRot(int index) const;
[[nodiscard]] Rotation GetRot() const;
void SetRot(const Rotation& rot);
// Setters
[[nodiscard]] int GetStateNumber() const;
[[nodiscard]] int GetTargetStateNumber() const;
void SetObjectID(GAME_OBJECT_ID id);
bool SetName(const std::string&);
void SetPosition(const Vec3& pos, sol::optional<bool> updateRoom);
std::unique_ptr<Room> GetRoom() const;
int GetRoomNumber() const;
void SetRotation(const Rotation& rot);
void SetStateNumber(int stateNumber);
[[nodiscard]] int GetAnimNumber() const;
[[nodiscard]] int GetAnimSlot() const;
void SetAnimNumber(int animNumber, sol::optional<int> slotIndex);
[[nodiscard]] int GetFrameNumber() const;
[[nodiscard]] int GetEndFrame() const;
void SetFrameNumber(int frameNumber);
[[nodiscard]] Vec3 GetVelocity() const;
void SetVelocity(Vec3 velocity);
[[nodiscard]] ScriptColor GetColor() const;
void SetColor(const ScriptColor& color);
[[nodiscard]] short GetHP() const;
void SetHP(short hp);
[[nodiscard]] short GetSlotHP() const;
[[nodiscard]] short GetOCB() const;
void SetOCB(short ocb);
[[nodiscard]] EffectType GetEffect() const;
void SetOcb(short ocb);
void SetEffect(EffectType effectType, sol::optional<float> timeout);
void SetCustomEffect(const ScriptColor& col1, const ScriptColor& col2, sol::optional<float> timeout);
[[nodiscard]] aiBitsType GetAIBits() const;
void SetAIBits(aiBitsType const & bits);
[[nodiscard]] short GetItemFlags(int index = 0) const;
void SetAIBits(aiBitsType const& bits);
void SetItemFlags(short value, int index = 0);
[[nodiscard]] short GetLocationAI() const;
void SetLocationAI(short value);
[[nodiscard]] short GetMeshCount() const;
[[nodiscard]] bool GetMeshVisible(int meshId) const;
void SetMeshVisible(int meshId, bool isVisible);
void ShatterMesh(int meshId);
[[nodiscard]] bool GetMeshSwapped(int meshId) const;
void SwapMesh(int meshId, int swapSlotId, sol::optional<int> swapMeshIndex);
void UnswapMesh(int meshId);
[[nodiscard]] bool GetHitStatus() const;
[[nodiscard]] bool GetActive() const;
void SetActive(bool isActive);
std::unique_ptr<Room> GetRoom() const;
[[nodiscard]] int GetRoomNumber() const;
void SetRoomNumber(int roomNumber);
void AttachObjCamera(short camMeshId, Moveable& mov, short targetMeshId);
void AnimFromObject(GAME_OBJECT_ID object, int animNumber, int stateID);
void EnableItem(sol::optional<float> timer);
void DisableItem();
void MakeInvisible();
void SetVisible(bool isVisible);
[[nodiscard]] bool GetCollidable();
void SetCollidable(bool isCollidable);
void Explode();
void Shatter();
void SetStatus(ItemStatus value);
void SetOnHit(const TypeOrNil<LevelFunc>& cb);
void SetOnKilled(const TypeOrNil<LevelFunc>& cb);
void SetOnCollidedWithObject(const TypeOrNil<LevelFunc>& cb);
void SetOnCollidedWithRoom(const TypeOrNil<LevelFunc>& cb);
[[nodiscard]] short GetStatus() const;
void SetStatus(ItemStatus value);
void Init();
friend bool operator ==(const Moveable&, const Moveable&);
friend void SetLevelFuncCallback(const TypeOrNil<LevelFunc>& cb, const std::string& callerName, Moveable& mov, std::string& toModify);
short GetIndex() const;
// Utilities
protected:
ItemInfo* m_item;
void Initialize();
void Invalidate();
void Destroy();
void ShatterMesh(int meshId);
void SwapMesh(int meshId, int swapSlotId, sol::optional<int> swapMeshIndex);
void UnswapMesh(int meshId);
void AttachObjCamera(short camMeshId, Moveable& mov, short targetMeshId);
void AnimFromObject(GAME_OBJECT_ID object, int animNumber, int stateID);
void EnableItem(sol::optional<float> timer);
void DisableItem();
void MakeInvisible();
void SetVisible(bool isVisible);
bool GetCollidable();
void SetCollidable(bool isCollidable);
void Explode();
void Shatter();
// Operators
Moveable& operator =(const Moveable& mov) = delete;
friend bool operator ==(const Moveable&, const Moveable&);
private:
short m_num;
bool m_initialized;
// Helpers
bool MeshExists(int number) const;
};

View file

@ -1,26 +1,21 @@
#pragma once
#include <string>
#include <unordered_map>
#include "Game/items.h"
/***
Constants for moveable statuses.
@enum Objects.MoveableStatus
@pragma nostrip
*/
/// Constants for moveable statuses.
// @enum Objects.MoveableStatus
// @pragma nostrip
/*** Table of Objects.MoveableStatus constants.
To be used with @{Objects.Moveable.GetStatus} and @{Objects.Moveable.SetStatus} functions.
- `INACTIVE` - object was never activated.
- `ACTIVE` - object is active.
- `DEACTIVATED` - object was active before and was deactivated.
- `INVISIBLE` - object is invisible.
@table Objects.MoveableStatus
*/
/// Table of Objects.MoveableStatus constants.
//
// To be used with @{Objects.Moveable.GetStatus} and @{Objects.Moveable.SetStatus} functions.
//
// - `INACTIVE` - moveable is inactive (was never activated).
// - `ACTIVE` - moveable is active.
// - `DEACTIVATED` - moveable is deactivated (was previously active and later deactivated).
// - `INVISIBLE` - moveable is invisible.
//
// @table Objects.MoveableStatus
static const std::unordered_map<std::string, ItemStatus> MOVEABLE_STATUSES
{

View file

@ -1,11 +1,9 @@
#pragma once
#include <functional>
#include <string>
#include "Scripting/Internal/ScriptAssert.h"
template <typename S> using callbackSetName = std::function<bool(std::string const&, S identifier)>;
using callbackRemoveName = std::function<bool(std::string const&)>;
template <typename S> using callbackSetName = std::function<bool(const std::string&, S identifier)>;
using callbackRemoveName = std::function<bool(const std::string&)>;
// Use the "curiously recurring template pattern" to allow classes to inherit static members and functions.
// T is the class that will both derive and instantiate this base class. S is the type used inside GameScriptWhateverInfo
@ -15,27 +13,27 @@ template <typename T, class S> class NamedBase
public:
static void SetNameCallbacks(callbackSetName<S> cbs, callbackRemoveName cbr)
{
s_callbackSetName = cbs;
s_callbackRemoveName = cbr;
_callbackSetName = cbs;
_callbackRemoveName = cbr;
}
protected:
static callbackSetName<S> s_callbackSetName;
static callbackRemoveName s_callbackRemoveName;
static callbackSetName<S> _callbackSetName;
static callbackRemoveName _callbackRemoveName;
};
// default callbacks
template <typename T, typename S> callbackSetName<S> NamedBase<T, S>::s_callbackSetName = [](std::string const& n, S identifier) {
std::string err = "\"Set Name\" callback is not set.";
// Default callbacks.
template <typename T, typename S> callbackSetName<S> NamedBase<T, S>::_callbackSetName = [](const std::string& name, S identifier)
{
auto err = std::string("\"Set Name\" callback is not set.");
throw TENScriptException(err);
return false;
};
};
// this could potentially be called by the GameScriptItemInfo destructor, and thus cannot throw
template <typename T, typename S> callbackRemoveName NamedBase<T, S>::s_callbackRemoveName = [](std::string const& n) {
// This could potentially be called by the GameScriptItemInfo destructor, and thus cannot throw.
template <typename T, typename S> callbackRemoveName NamedBase<T, S>::_callbackRemoveName = [](const std::string& name)
{
TENLog("\"Remove Name\" callback is not set.", LogLevel::Error);
std::terminate();
return false;
};
};

View file

@ -131,7 +131,7 @@ private:
if (key.empty())
return false;
auto p = std::pair< const std::string&, VarMapVal>{ key, val };
auto p = std::pair<const std::string&, VarMapVal>(key, val);
return m_nameMap.insert(p).second;
}

View file

@ -89,9 +89,9 @@
return;
// Remove previous name if it already exists.
if (s_callbackSetName(name, _room))
if (_callbackSetName(name, _room))
{
s_callbackRemoveName(_room.Name);
_callbackRemoveName(_room.Name);
_room.Name = name;
}
else

View file

@ -83,10 +83,10 @@ void Sink::SetName(const std::string& id)
return;
}
if (s_callbackSetName(id, m_sink))
if (_callbackSetName(id, m_sink))
{
// remove the old name if we have one
s_callbackRemoveName(m_sink.Name);
_callbackRemoveName(m_sink.Name);
m_sink.Name = id;
}
else

View file

@ -82,10 +82,10 @@ void SoundSource::SetName(std::string const& id)
return;
}
if (s_callbackSetName(id, m_soundSource))
if (_callbackSetName(id, m_soundSource))
{
// remove the old name if we have one
s_callbackRemoveName(m_soundSource.Name);
_callbackRemoveName(m_soundSource.Name);
m_soundSource.Name = id;
}
else

View file

@ -228,10 +228,10 @@ void Static::SetName(std::string const & name)
return;
}
if (s_callbackSetName(name, m_mesh))
if (_callbackSetName(name, m_mesh))
{
// remove the old name if we have one
s_callbackRemoveName(m_mesh.Name);
_callbackRemoveName(m_mesh.Name);
m_mesh.Name = name;
}
else

View file

@ -90,9 +90,9 @@ void Volume::SetName(const std::string& name)
return;
// Remove previous name if it exists.
if (s_callbackSetName(name, _volume))
if (_callbackSetName(name, _volume))
{
s_callbackRemoveName(_volume.Name);
_callbackRemoveName(_volume.Name);
_volume.Name = name;
}
else