|
|
@ -124,7 +124,7 @@ namespace MWLua
|
|
|
|
newPtr = cls.moveToCell(ptr, *destCell, toPos(pos, rot));
|
|
|
|
newPtr = cls.moveToCell(ptr, *destCell, toPos(pos, rot));
|
|
|
|
ptr.getCellRef().unsetRefNum();
|
|
|
|
ptr.getCellRef().unsetRefNum();
|
|
|
|
ptr.getRefData().setLuaScripts(nullptr);
|
|
|
|
ptr.getRefData().setLuaScripts(nullptr);
|
|
|
|
ptr.getRefData().setCount(0);
|
|
|
|
ptr.getCellRef().setCount(0);
|
|
|
|
ESM::RefId script = cls.getScript(newPtr);
|
|
|
|
ESM::RefId script = cls.getScript(newPtr);
|
|
|
|
if (!script.empty())
|
|
|
|
if (!script.empty())
|
|
|
|
world->getLocalScripts().add(script, newPtr);
|
|
|
|
world->getLocalScripts().add(script, newPtr);
|
|
|
@ -256,7 +256,7 @@ namespace MWLua
|
|
|
|
[types = getTypeToPackageTable(context.mLua->sol())](
|
|
|
|
[types = getTypeToPackageTable(context.mLua->sol())](
|
|
|
|
const ObjectT& o) mutable { return types[getLiveCellRefType(o.ptr().mRef)]; });
|
|
|
|
const ObjectT& o) mutable { return types[getLiveCellRefType(o.ptr().mRef)]; });
|
|
|
|
|
|
|
|
|
|
|
|
objectT["count"] = sol::readonly_property([](const ObjectT& o) { return o.ptr().getRefData().getCount(); });
|
|
|
|
objectT["count"] = sol::readonly_property([](const ObjectT& o) { return o.ptr().getCellRef().getCount(); });
|
|
|
|
objectT[sol::meta_function::equal_to] = [](const ObjectT& a, const ObjectT& b) { return a.id() == b.id(); };
|
|
|
|
objectT[sol::meta_function::equal_to] = [](const ObjectT& a, const ObjectT& b) { return a.id() == b.id(); };
|
|
|
|
objectT[sol::meta_function::to_string] = &ObjectT::toString;
|
|
|
|
objectT[sol::meta_function::to_string] = &ObjectT::toString;
|
|
|
|
objectT["sendEvent"] = [context](const ObjectT& dest, std::string eventName, const sol::object& eventData) {
|
|
|
|
objectT["sendEvent"] = [context](const ObjectT& dest, std::string eventName, const sol::object& eventData) {
|
|
|
@ -340,10 +340,10 @@ namespace MWLua
|
|
|
|
|
|
|
|
|
|
|
|
auto isEnabled = [](const ObjectT& o) { return o.ptr().getRefData().isEnabled(); };
|
|
|
|
auto isEnabled = [](const ObjectT& o) { return o.ptr().getRefData().isEnabled(); };
|
|
|
|
auto setEnabled = [context](const GObject& object, bool enable) {
|
|
|
|
auto setEnabled = [context](const GObject& object, bool enable) {
|
|
|
|
if (enable && object.ptr().getRefData().isDeleted())
|
|
|
|
if (enable && object.ptr().mRef->isDeleted())
|
|
|
|
throw std::runtime_error("Object is removed");
|
|
|
|
throw std::runtime_error("Object is removed");
|
|
|
|
context.mLuaManager->addAction([object, enable] {
|
|
|
|
context.mLuaManager->addAction([object, enable] {
|
|
|
|
if (object.ptr().getRefData().isDeleted())
|
|
|
|
if (object.ptr().mRef->isDeleted())
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
if (object.ptr().isInCell())
|
|
|
|
if (object.ptr().isInCell())
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -417,20 +417,20 @@ namespace MWLua
|
|
|
|
|
|
|
|
|
|
|
|
using DelayedRemovalFn = std::function<void(MWWorld::Ptr)>;
|
|
|
|
using DelayedRemovalFn = std::function<void(MWWorld::Ptr)>;
|
|
|
|
auto removeFn = [](const MWWorld::Ptr ptr, int countToRemove) -> std::optional<DelayedRemovalFn> {
|
|
|
|
auto removeFn = [](const MWWorld::Ptr ptr, int countToRemove) -> std::optional<DelayedRemovalFn> {
|
|
|
|
int rawCount = ptr.getRefData().getCount(false);
|
|
|
|
int rawCount = ptr.getCellRef().getCount(false);
|
|
|
|
int currentCount = std::abs(rawCount);
|
|
|
|
int currentCount = std::abs(rawCount);
|
|
|
|
int signedCountToRemove = (rawCount < 0 ? -1 : 1) * countToRemove;
|
|
|
|
int signedCountToRemove = (rawCount < 0 ? -1 : 1) * countToRemove;
|
|
|
|
|
|
|
|
|
|
|
|
if (countToRemove <= 0 || countToRemove > currentCount)
|
|
|
|
if (countToRemove <= 0 || countToRemove > currentCount)
|
|
|
|
throw std::runtime_error("Can't remove " + std::to_string(countToRemove) + " of "
|
|
|
|
throw std::runtime_error("Can't remove " + std::to_string(countToRemove) + " of "
|
|
|
|
+ std::to_string(currentCount) + " items");
|
|
|
|
+ std::to_string(currentCount) + " items");
|
|
|
|
ptr.getRefData().setCount(rawCount - signedCountToRemove); // Immediately change count
|
|
|
|
ptr.getCellRef().setCount(rawCount - signedCountToRemove); // Immediately change count
|
|
|
|
if (!ptr.getContainerStore() && currentCount > countToRemove)
|
|
|
|
if (!ptr.getContainerStore() && currentCount > countToRemove)
|
|
|
|
return std::nullopt;
|
|
|
|
return std::nullopt;
|
|
|
|
// Delayed action to trigger side effects
|
|
|
|
// Delayed action to trigger side effects
|
|
|
|
return [signedCountToRemove](MWWorld::Ptr ptr) {
|
|
|
|
return [signedCountToRemove](MWWorld::Ptr ptr) {
|
|
|
|
// Restore the original count
|
|
|
|
// Restore the original count
|
|
|
|
ptr.getRefData().setCount(ptr.getRefData().getCount(false) + signedCountToRemove);
|
|
|
|
ptr.getCellRef().setCount(ptr.getCellRef().getCount(false) + signedCountToRemove);
|
|
|
|
// And now remove properly
|
|
|
|
// And now remove properly
|
|
|
|
if (ptr.getContainerStore())
|
|
|
|
if (ptr.getContainerStore())
|
|
|
|
ptr.getContainerStore()->remove(ptr, std::abs(signedCountToRemove), false);
|
|
|
|
ptr.getContainerStore()->remove(ptr, std::abs(signedCountToRemove), false);
|
|
|
@ -443,7 +443,7 @@ namespace MWLua
|
|
|
|
};
|
|
|
|
};
|
|
|
|
objectT["remove"] = [removeFn, context](const GObject& object, sol::optional<int> count) {
|
|
|
|
objectT["remove"] = [removeFn, context](const GObject& object, sol::optional<int> count) {
|
|
|
|
std::optional<DelayedRemovalFn> delayed
|
|
|
|
std::optional<DelayedRemovalFn> delayed
|
|
|
|
= removeFn(object.ptr(), count.value_or(object.ptr().getRefData().getCount()));
|
|
|
|
= removeFn(object.ptr(), count.value_or(object.ptr().getCellRef().getCount()));
|
|
|
|
if (delayed.has_value())
|
|
|
|
if (delayed.has_value())
|
|
|
|
context.mLuaManager->addAction([fn = *delayed, object] { fn(object.ptr()); });
|
|
|
|
context.mLuaManager->addAction([fn = *delayed, object] { fn(object.ptr()); });
|
|
|
|
};
|
|
|
|
};
|
|
|
@ -463,7 +463,7 @@ namespace MWLua
|
|
|
|
};
|
|
|
|
};
|
|
|
|
objectT["moveInto"] = [removeFn, context](const GObject& object, const sol::object& dest) {
|
|
|
|
objectT["moveInto"] = [removeFn, context](const GObject& object, const sol::object& dest) {
|
|
|
|
const MWWorld::Ptr& ptr = object.ptr();
|
|
|
|
const MWWorld::Ptr& ptr = object.ptr();
|
|
|
|
int count = ptr.getRefData().getCount();
|
|
|
|
int count = ptr.getCellRef().getCount();
|
|
|
|
MWWorld::Ptr destPtr;
|
|
|
|
MWWorld::Ptr destPtr;
|
|
|
|
if (dest.is<GObject>())
|
|
|
|
if (dest.is<GObject>())
|
|
|
|
destPtr = dest.as<GObject>().ptr();
|
|
|
|
destPtr = dest.as<GObject>().ptr();
|
|
|
@ -474,9 +474,9 @@ namespace MWLua
|
|
|
|
std::optional<DelayedRemovalFn> delayedRemovalFn = removeFn(ptr, count);
|
|
|
|
std::optional<DelayedRemovalFn> delayedRemovalFn = removeFn(ptr, count);
|
|
|
|
context.mLuaManager->addAction([item = object, count, cont = GObject(destPtr), delayedRemovalFn] {
|
|
|
|
context.mLuaManager->addAction([item = object, count, cont = GObject(destPtr), delayedRemovalFn] {
|
|
|
|
const MWWorld::Ptr& oldPtr = item.ptr();
|
|
|
|
const MWWorld::Ptr& oldPtr = item.ptr();
|
|
|
|
auto& refData = oldPtr.getRefData();
|
|
|
|
auto& refData = oldPtr.getCellRef();
|
|
|
|
refData.setCount(count); // temporarily undo removal to run ContainerStore::add
|
|
|
|
refData.setCount(count); // temporarily undo removal to run ContainerStore::add
|
|
|
|
refData.enable();
|
|
|
|
oldPtr.getRefData().enable();
|
|
|
|
cont.ptr().getClass().getContainerStore(cont.ptr()).add(oldPtr, count, false);
|
|
|
|
cont.ptr().getClass().getContainerStore(cont.ptr()).add(oldPtr, count, false);
|
|
|
|
refData.setCount(0);
|
|
|
|
refData.setCount(0);
|
|
|
|
if (delayedRemovalFn.has_value())
|
|
|
|
if (delayedRemovalFn.has_value())
|
|
|
@ -487,7 +487,7 @@ namespace MWLua
|
|
|
|
const osg::Vec3f& pos, const sol::object& options) {
|
|
|
|
const osg::Vec3f& pos, const sol::object& options) {
|
|
|
|
MWWorld::CellStore* cell = findCell(cellOrName, pos);
|
|
|
|
MWWorld::CellStore* cell = findCell(cellOrName, pos);
|
|
|
|
MWWorld::Ptr ptr = object.ptr();
|
|
|
|
MWWorld::Ptr ptr = object.ptr();
|
|
|
|
int count = ptr.getRefData().getCount();
|
|
|
|
int count = ptr.getCellRef().getCount();
|
|
|
|
if (count == 0)
|
|
|
|
if (count == 0)
|
|
|
|
throw std::runtime_error("Object is either removed or already in the process of teleporting");
|
|
|
|
throw std::runtime_error("Object is either removed or already in the process of teleporting");
|
|
|
|
osg::Vec3f rot = ptr.getRefData().getPosition().asRotationVec3();
|
|
|
|
osg::Vec3f rot = ptr.getRefData().getPosition().asRotationVec3();
|
|
|
@ -508,9 +508,9 @@ namespace MWLua
|
|
|
|
context.mLuaManager->addAction(
|
|
|
|
context.mLuaManager->addAction(
|
|
|
|
[object, cell, pos, rot, count, delayedRemovalFn, placeOnGround] {
|
|
|
|
[object, cell, pos, rot, count, delayedRemovalFn, placeOnGround] {
|
|
|
|
MWWorld::Ptr oldPtr = object.ptr();
|
|
|
|
MWWorld::Ptr oldPtr = object.ptr();
|
|
|
|
oldPtr.getRefData().setCount(count);
|
|
|
|
oldPtr.getCellRef().setCount(count);
|
|
|
|
MWWorld::Ptr newPtr = oldPtr.getClass().moveToCell(oldPtr, *cell);
|
|
|
|
MWWorld::Ptr newPtr = oldPtr.getClass().moveToCell(oldPtr, *cell);
|
|
|
|
oldPtr.getRefData().setCount(0);
|
|
|
|
oldPtr.getCellRef().setCount(0);
|
|
|
|
newPtr.getRefData().disable();
|
|
|
|
newPtr.getRefData().disable();
|
|
|
|
teleportNotPlayer(newPtr, cell, pos, rot, placeOnGround);
|
|
|
|
teleportNotPlayer(newPtr, cell, pos, rot, placeOnGround);
|
|
|
|
delayedRemovalFn(oldPtr);
|
|
|
|
delayedRemovalFn(oldPtr);
|
|
|
@ -522,10 +522,10 @@ namespace MWLua
|
|
|
|
[cell, pos, rot, placeOnGround] { teleportPlayer(cell, pos, rot, placeOnGround); });
|
|
|
|
[cell, pos, rot, placeOnGround] { teleportPlayer(cell, pos, rot, placeOnGround); });
|
|
|
|
else
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
|
ptr.getRefData().setCount(0);
|
|
|
|
ptr.getCellRef().setCount(0);
|
|
|
|
context.mLuaManager->addAction(
|
|
|
|
context.mLuaManager->addAction(
|
|
|
|
[object, cell, pos, rot, count, placeOnGround] {
|
|
|
|
[object, cell, pos, rot, count, placeOnGround] {
|
|
|
|
object.ptr().getRefData().setCount(count);
|
|
|
|
object.ptr().getCellRef().setCount(count);
|
|
|
|
teleportNotPlayer(object.ptr(), cell, pos, rot, placeOnGround);
|
|
|
|
teleportNotPlayer(object.ptr(), cell, pos, rot, placeOnGround);
|
|
|
|
},
|
|
|
|
},
|
|
|
|
"TeleportAction");
|
|
|
|
"TeleportAction");
|
|
|
|