// // Created by koncord on 26.08.17. // #include #include "Object.hpp" #include "Player.hpp" #include "Networking.hpp" using namespace std; void Object::Init(LuaState &lua) { lua.getState()->new_usertype("Object", "refId", sol::property(&BaseObject::getRefId, &BaseObject::setRefId), "refNum", sol::property(&BaseObject::getRefNum, &BaseObject::setRefNum), "mpNum", sol::property(&BaseObject::getMpNum, &BaseObject::setMpNum), "setPosition", &Object::setPosition, "getPosition", &Object::getPosition, "setRotation", &Object::setRotation, "getRotation", &Object::getRotation, "count", sol::property(&Object::getCount, &Object::setCount), "goldValue", sol::property(&Object::getGoldValue, &Object::setGoldValue), "scale", sol::property(&Object::getScale, &Object::setScale), "state", sol::property(&Object::getState, &Object::setState), "doorState", sol::property(&Object::getDoorState, &Object::setDoorState), "lockLevel", sol::property(&Object::getLockLevel, &Object::setLockLevel), "setDisarmState", &Object::setDisarmState, "setMasterState", &Object::setMasterState ); } Object::Object() { } Object::~Object() { } void Object::update() { } tuple Object::getPosition() const { return make_tuple(object.position.pos[0], object.position.pos[1], object.position.pos[2]); } void Object::setPosition(float x, float y, float z) { object.position.pos[0] = x; object.position.pos[1] = y; object.position.pos[2] = z; changedObjectPlace = true; } tuple Object::getRotation() const { return make_tuple(object.position.rot[0], object.position.rot[1], object.position.rot[2]); } void Object::setRotation(float x, float y, float z) { object.position.rot[0] = x; object.position.rot[1] = y; object.position.rot[2] = z; changedObjectPlace = true; } BaseObject::BaseObject(): changedBase(false), copied(false) { } string BaseObject::getRefId() const { return object.refId; } void BaseObject::setRefId(const string &refId) { changedBase = true; object.refId = refId; } int BaseObject::getRefNum() const { return object.refNumIndex; } void BaseObject::setRefNum(int refNum) { changedBase = true; object.refNumIndex = refNum; } int BaseObject::getMpNum() const { return object.mpNum; } void BaseObject::setMpNum(int mpNum) { changedBase = true; object.mpNum = mpNum; } int Object::getCount() const { return object.count; } void Object::setCount(int count) { changedObjectPlace = true; object.count = count; } int Object::getCharge() const { return object.charge; } void Object::setCharge(int charge) { changedObjectPlace = true; object.charge = charge; } int Object::getGoldValue() const { return object.goldValue; } void Object::setGoldValue(int gold) { changedObjectPlace = true; object.goldValue = gold; } float Object::getScale() const { return object.scale; } void Object::setScale(float scale) { changedObjectScale = true; object.scale = scale; } bool Object::getState() const { return object.objectState; } void Object::setState(bool state) { changedObjectState = true; object.objectState = state; } int Object::getDoorState() const { return object.doorState; } void Object::setDoorState(int state) { changedDoorState = true; object.doorState = state; } int Object::getLockLevel() const { return object.lockLevel; } void Object::setLockLevel(int locklevel) { changedObjectLock = true; object.lockLevel = locklevel; } void Object::setDisarmState(bool state) { changedObjectTrap = true; object.isDisarmed = state; } void Object::setMasterState(bool state) { changedObjectSpawn = true; object.hasMaster = state; } void Container::Init(LuaState &lua) { lua.getState()->new_usertype("Container", "refId", sol::property(&BaseObject::getRefId, &BaseObject::setRefId), "refNum", sol::property(&BaseObject::getRefNum, &BaseObject::setRefNum), "mpNum", sol::property(&BaseObject::getMpNum, &BaseObject::setMpNum), "getItem", &Container::getItem, "addItem", &Container::addItem, "setItem", &Container::setItem, "getActionCount", &Container::getActionCount ); } Container::Container() { } tuple Container::getItem(int i) const { auto &item = object.containerItems.at(i); return make_tuple(item.refId, item.count, item.charge); } void Container::setItem(int i, const string &refId, int count, int charge) { auto &item = object.containerItems.at(i); item.refId = refId; item.count = count; item.charge = charge; changed = true; } void Container::addItem(const string &refId, int count, int charge) { mwmp::ContainerItem item; item.refId = refId; item.count = count; item.charge = charge; object.containerItems.push_back(item); changed = true; } int Container::getActionCount(int i) const { return object.containerItems.at(i).actionCount; } size_t Container::size() const { return object.containerItems.size(); } void ObjectController::Init(LuaState &lua) { sol::table objectCtrl = lua.getState()->create_table("ObjectCtrl"); objectCtrl.set_function("sendObjects", [&lua](shared_ptr player, shared_ptr>> objects, const std::string &cellDescription) { return lua.getObjectCtrl().sendObjects(player, objects, Utils::getCellFromDescription(cellDescription)); }); objectCtrl.set_function("sendContainers", [&lua](shared_ptr player, shared_ptr>> objects, const std::string &cellDescription) { return lua.getObjectCtrl().sendContainers(player, objects, Utils::getCellFromDescription(cellDescription)); }); objectCtrl.set_function("requestContainers", [&lua](shared_ptr player) { return lua.getObjectCtrl().requestContainers(player); }); } shared_ptr>> ObjectController::copyObjects(mwmp::BaseEvent &event) { auto objects = make_shared>>(); for(auto &obj : event.worldObjects) { auto object = new Object; object->copied = true; object->object = obj; objects->emplace_back(object); } return objects; } shared_ptr>> ObjectController::copyContainers(mwmp::BaseEvent &event) { auto containers = make_shared>>(); for(auto &obj : event.worldObjects) { auto container = new Container; container->copied = true; container->object = obj; containers->emplace_back(container); } return containers; } void ObjectController::sendObjects(shared_ptr player, shared_ptr>> objects, const ESM::Cell &cell) { enum Type { DOOR_STATE = 0, OBJECT_STATE, OBJECT_SCALE, OBJECT_TRAP, OBJECT_LOCK, OBJECT_DELETE, OBJECT_SPAWN, OBJECT_PLACE, LAST }; mwmp::BaseEvent events[Type::LAST]; bool changed[Type::LAST]; for(auto &e : events) { e.action = mwmp::BaseEvent::SET; e.guid = player->guid; e.cell = cell; } for(auto &object : *objects) { //sendObject(player.get(), object.get()); bool validNewObjOrCopy = (!object->copied && object->changedBase) || object->copied; if(object->changedDoorState && validNewObjOrCopy) { changed[Type::DOOR_STATE] = true; events[Type::DOOR_STATE].worldObjects.push_back(object->object); } if(object->changedObjectState && validNewObjOrCopy) { changed[Type::OBJECT_STATE] = true; events[Type::OBJECT_STATE].worldObjects.push_back(object->object); } if(object->changedObjectScale && validNewObjOrCopy) { changed[Type::OBJECT_SCALE] = true; events[Type::OBJECT_SCALE].worldObjects.push_back(object->object); } if(object->changedObjectTrap && validNewObjOrCopy) { changed[Type::OBJECT_TRAP] = true; events[Type::OBJECT_TRAP].worldObjects.push_back(object->object); } if(object->changedObjectLock && validNewObjOrCopy) { changed[Type::OBJECT_LOCK] = true; events[Type::OBJECT_LOCK].worldObjects.push_back(object->object); } if(object->changedObjectDelete && validNewObjOrCopy) { changed[Type::OBJECT_DELETE] = true; events[Type::OBJECT_DELETE].worldObjects.push_back(object->object); } if(object->changedObjectSpawn && validNewObjOrCopy) { changed[Type::OBJECT_SPAWN] = true; events[Type::OBJECT_SPAWN].worldObjects.push_back(object->object); } if(object->changedObjectPlace && validNewObjOrCopy) { changed[Type::OBJECT_PLACE] = true; events[Type::OBJECT_PLACE].worldObjects.push_back(object->object); } } auto worldCtrl = mwmp::Networking::get().getWorldPacketController(); if(changed[Type::DOOR_STATE]) { auto packet = worldCtrl->GetPacket(ID_DOOR_STATE); auto &event = events[Type::DOOR_STATE]; packet->setEvent(&event); packet->Send(event.guid); } if(changed[Type::OBJECT_STATE]) { auto packet = worldCtrl->GetPacket(ID_OBJECT_STATE); auto &event = events[Type::OBJECT_STATE]; packet->setEvent(&event); packet->Send(event.guid); } if(changed[Type::OBJECT_SCALE]) { auto packet = worldCtrl->GetPacket(ID_OBJECT_SCALE); auto &event = events[Type::OBJECT_SCALE]; packet->setEvent(&event); packet->Send(event.guid); } if(changed[Type::OBJECT_TRAP]) { auto packet = worldCtrl->GetPacket(ID_OBJECT_TRAP); auto &event = events[Type::OBJECT_TRAP]; packet->setEvent(&event); packet->Send(event.guid); } if(changed[Type::OBJECT_LOCK]) { auto packet = worldCtrl->GetPacket(ID_OBJECT_LOCK); auto &event = events[Type::OBJECT_LOCK]; packet->setEvent(&event); packet->Send(event.guid); } if(changed[Type::OBJECT_DELETE]) { auto packet = worldCtrl->GetPacket(ID_OBJECT_DELETE); auto &event = events[Type::OBJECT_DELETE]; packet->setEvent(&event); packet->Send(event.guid); } if(changed[Type::OBJECT_SCALE]) { auto packet = worldCtrl->GetPacket(ID_OBJECT_SPAWN); auto &event = events[Type::OBJECT_SCALE]; packet->setEvent(&event); packet->Send(event.guid); } if(changed[Type::OBJECT_PLACE]) { auto packet = worldCtrl->GetPacket(ID_OBJECT_PLACE); auto &event = events[Type::OBJECT_PLACE]; packet->setEvent(&event); packet->Send(event.guid); } } void ObjectController::sendContainers(shared_ptr player, shared_ptr>> objects, const ESM::Cell &cell) { mwmp::BaseEvent event; event.cell = cell; event.action = mwmp::BaseEvent::SET; event.guid = player->guid; for(auto &object : *objects) { bool validNewObjOrCopy = (!object->copied && object->changedBase) || object->copied; if(object->changed && validNewObjOrCopy) event.worldObjects.push_back(object->object); } auto packet = mwmp::Networking::get().getWorldPacketController()->GetPacket(ID_CONTAINER); packet->setEvent(&event); packet->Send(event.guid); } void ObjectController::requestContainers(shared_ptr player) { mwmp::BaseEvent event; event.action = mwmp::BaseEvent::REQUEST; event.guid = player->guid; event.cell = player->cell; auto packet = mwmp::Networking::get().getWorldPacketController()->GetPacket(ID_CONTAINER); packet->setEvent(&event); packet->Send(event.guid); }