[General] Modernize Script API
This commit changes the style of tes3mp serverside scripting mods. Short list of changes: * Break compatibility with old server mods * OOP style lua API * Basic dependency checker, allowing the installation of multiple server mods without changing configs * Remove support for C++ plugins * Change outdated LuaBridge to [sol2](https://github.com/ThePhD/sol2); * Support GCC, Clang and MSVC compilers * New environment variables: "TES3MP_SERVER_DIR" and "TES3MP_SERVER_USERDIR"; * New entity "Command controller" for registering new chat commands; * New Event system * Simplified Timer API * All Lua mods now run in their own environments * Add global namespace - Data that can be used for communicating between mods * Player and Actor inherit base class NetActorpull/276/head
parent
77ce05b7d6
commit
2d0840cb3a
@ -1,3 +1,6 @@
|
||||
[submodule "extern/breakpad"]
|
||||
path = extern/breakpad
|
||||
url = https://chromium.googlesource.com/breakpad/breakpad
|
||||
[submodule "extern/sol"]
|
||||
path = extern/sol
|
||||
url = https://github.com/ThePhD/sol2
|
||||
|
@ -0,0 +1,270 @@
|
||||
//
|
||||
// Created by koncord on 25.08.17.
|
||||
//
|
||||
|
||||
#include <components/openmw-mp/NetworkMessages.hpp>
|
||||
#include "Actors.hpp"
|
||||
#include "Script/LuaState.hpp"
|
||||
#include "Networking.hpp"
|
||||
#include "Cell.hpp"
|
||||
#include "CellController.hpp"
|
||||
#include "Player.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
void Actor::Init(LuaState &lua)
|
||||
{
|
||||
lua.getState()->new_usertype<Actor>("Actor",
|
||||
"getPosition", &NetActor::getPosition,
|
||||
"setPosition", &NetActor::setPosition,
|
||||
"getRotation", &NetActor::getRotation,
|
||||
"setRotation", &NetActor::setRotation,
|
||||
|
||||
"getHealth", &NetActor::getHealth,
|
||||
"setHealth", &NetActor::setHealth,
|
||||
"getMagicka", &NetActor::getMagicka,
|
||||
"setMagicka", &NetActor::setMagicka,
|
||||
"getFatigue", &NetActor::getFatigue,
|
||||
"setFatigue", &NetActor::setFatigue,
|
||||
|
||||
"getCell", &NetActor::getCell,
|
||||
"getInventory", &NetActor::getInventory,
|
||||
|
||||
"refId", sol::property(&Actor::getRefId, &Actor::setRefId),
|
||||
"refNumIndex", sol::property(&Actor::getRefNumIndex, &Actor::setRefNumIndex),
|
||||
"mpNum", sol::property(&Actor::getMpNum, &Actor::setMpNum)
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
Actor::Actor() : NetActor()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::string Actor::getRefId() const
|
||||
{
|
||||
return actor->refId;
|
||||
}
|
||||
|
||||
void Actor::setRefId(const std::string &refId)
|
||||
{
|
||||
actor->refId = refId;
|
||||
}
|
||||
|
||||
int Actor::getRefNumIndex() const
|
||||
{
|
||||
return actor->refNumIndex;
|
||||
}
|
||||
|
||||
void Actor::setRefNumIndex(int refNumIndex)
|
||||
{
|
||||
actor->refNumIndex = refNumIndex;
|
||||
}
|
||||
|
||||
int Actor::getMpNum() const
|
||||
{
|
||||
return actor->mpNum;
|
||||
}
|
||||
|
||||
void Actor::setMpNum(int mpNum)
|
||||
{
|
||||
actor->mpNum = mpNum;
|
||||
}
|
||||
|
||||
bool Actor::doesHavePosition() const
|
||||
{
|
||||
return actor->hasPositionData;
|
||||
}
|
||||
|
||||
bool Actor::doesHaveStatsDynamic() const
|
||||
{
|
||||
return actor->hasStatsDynamicData;
|
||||
}
|
||||
|
||||
void ActorController::Init(LuaState &lua)
|
||||
{
|
||||
sol::table playersTable = lua.getState()->create_named_table("Actors");
|
||||
|
||||
playersTable.set_function("createActor", [&lua](){
|
||||
lua.getActorCtrl().createActor();
|
||||
});
|
||||
|
||||
playersTable.set_function("sendActors", [&lua](shared_ptr<Player> player, vector<shared_ptr<Actor>> actors,
|
||||
bool sendToAll) {
|
||||
lua.getActorCtrl().sendActors(player, actors, sendToAll);
|
||||
});
|
||||
|
||||
playersTable.set_function("sendList", [&lua](shared_ptr<Player> player, vector<shared_ptr<Actor>> actors,
|
||||
bool sendToAll) {
|
||||
lua.getActorCtrl().sendList(player, actors, sendToAll);
|
||||
});
|
||||
|
||||
playersTable.set_function("requestList", [&lua](shared_ptr<Player> player){
|
||||
lua.getActorCtrl().requestList(player);
|
||||
});
|
||||
|
||||
playersTable.set_function("getActors", [&lua](shared_ptr<Player> player){
|
||||
lua.getActorCtrl().getActors(player);
|
||||
});
|
||||
}
|
||||
|
||||
ActorController::ActorController()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ActorController::~ActorController()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::shared_ptr<Actor> ActorController::createActor()
|
||||
{
|
||||
Actor *actor = new Actor();
|
||||
actor->actor.reset(new mwmp::BaseActor);
|
||||
|
||||
return shared_ptr<Actor>(actor);
|
||||
}
|
||||
|
||||
void ActorController::sendActors(std::shared_ptr<Player> player, std::vector<std::shared_ptr<Actor>> actors, bool sendToAll)
|
||||
{
|
||||
actorList.cell = player->cell;
|
||||
actorList.guid = player->guid;
|
||||
|
||||
bool positionChanged = false;
|
||||
bool statsChanged = false;
|
||||
bool attributesChanged = false;
|
||||
bool skillsChanged = false;
|
||||
bool baseInfoChanged = false;
|
||||
bool equipmentChanged = false;
|
||||
bool changedCell = false;
|
||||
|
||||
actorList.baseActors.clear();
|
||||
for (auto &actor : actors)
|
||||
{
|
||||
actorList.baseActors.push_back(actor->actor);
|
||||
|
||||
if (actor->positionChanged)
|
||||
positionChanged = true;
|
||||
if (actor->statsChanged)
|
||||
statsChanged = true;
|
||||
if (actor->attributesChanged)
|
||||
attributesChanged = true;
|
||||
if (actor->skillsChanged)
|
||||
skillsChanged = true;
|
||||
if (actor->baseInfoChanged)
|
||||
baseInfoChanged = true;
|
||||
if (actor->inventory.isEquipmentChanged())
|
||||
{
|
||||
equipmentChanged = true;
|
||||
actor->inventory.resetEquipmentFlag();
|
||||
}
|
||||
if (actor->cellAPI.isChangedCell())
|
||||
{
|
||||
changedCell = true;
|
||||
actor->cellAPI.resetChangedCell();
|
||||
}
|
||||
actor->resetUpdateFlags();
|
||||
}
|
||||
|
||||
auto actorCtrl = mwmp::Networking::get().getActorPacketController();
|
||||
Cell *serverCell = nullptr;
|
||||
|
||||
if (sendToAll)
|
||||
serverCell = CellController::get()->getCell(&actorList.cell);
|
||||
|
||||
if (positionChanged)
|
||||
{
|
||||
auto packet = actorCtrl->GetPacket(ID_ACTOR_POSITION);
|
||||
|
||||
packet->setActorList(&actorList);
|
||||
packet->Send(actorList.guid);
|
||||
|
||||
if (sendToAll)
|
||||
serverCell->sendToLoaded(packet, &actorList);
|
||||
}
|
||||
if (statsChanged)
|
||||
{
|
||||
auto packet = actorCtrl->GetPacket(ID_ACTOR_STATS_DYNAMIC);
|
||||
|
||||
packet->setActorList(&actorList);
|
||||
packet->Send(actorList.guid);
|
||||
|
||||
if (sendToAll)
|
||||
serverCell->sendToLoaded(packet, &actorList);
|
||||
|
||||
}
|
||||
/*if (attributesChanged)
|
||||
{
|
||||
auto packet = actorCtrl->GetPacket(ID_ACTOR_POSITION);
|
||||
|
||||
}
|
||||
if (skillsChanged)
|
||||
{
|
||||
auto packet = actorCtrl->GetPacket(ID_ACTOR_POSITION);
|
||||
|
||||
}
|
||||
if (baseInfoChanged)
|
||||
{
|
||||
auto packet = actorCtrl->GetPacket(ID_ACTOR_POSITION);
|
||||
|
||||
}*/
|
||||
|
||||
if (equipmentChanged)
|
||||
{
|
||||
auto packet = actorCtrl->GetPacket(ID_ACTOR_EQUIPMENT);
|
||||
packet->setActorList(&actorList);
|
||||
packet->Send(actorList.guid);
|
||||
|
||||
if (sendToAll)
|
||||
serverCell->sendToLoaded(packet, &actorList);
|
||||
}
|
||||
if (changedCell)
|
||||
{
|
||||
auto packet = actorCtrl->GetPacket(ID_ACTOR_CELL_CHANGE);
|
||||
packet->setActorList(&actorList);
|
||||
packet->Send(actorList.guid);
|
||||
|
||||
if (sendToAll)
|
||||
serverCell->sendToLoaded(packet, &actorList);
|
||||
}
|
||||
}
|
||||
|
||||
void ActorController::sendList(std::shared_ptr<Player> player, std::vector<std::shared_ptr<Actor>> actors, bool sendToAll)
|
||||
{
|
||||
actorList.cell = player->cell;
|
||||
actorList.guid = player->guid;
|
||||
actorList.action = mwmp::BaseActorList::SET;
|
||||
|
||||
auto packet = mwmp::Networking::get().getActorPacketController()->GetPacket(ID_ACTOR_LIST);
|
||||
packet->setActorList(&actorList);
|
||||
packet->Send(actorList.guid);
|
||||
}
|
||||
|
||||
void ActorController::requestList(std::shared_ptr<Player> player)
|
||||
{
|
||||
actorList.cell = player->cell;
|
||||
actorList.guid = player->guid;
|
||||
actorList.action = mwmp::BaseActorList::REQUEST;
|
||||
|
||||
auto packet = mwmp::Networking::get().getActorPacketController()->GetPacket(ID_ACTOR_LIST);
|
||||
packet->setActorList(&actorList);
|
||||
packet->Send(actorList.guid);
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<Actor>> ActorController::getActors(std::shared_ptr<Player> player)
|
||||
{
|
||||
Cell *serverCell = CellController::get()->getCell(&player->cell);
|
||||
|
||||
std::vector<std::shared_ptr<Actor>> actorList;
|
||||
|
||||
for (auto actor : serverCell->getActorList()->baseActors)
|
||||
{
|
||||
Actor *a = new Actor;
|
||||
a->actor = actor;
|
||||
actorList.emplace_back(a);
|
||||
}
|
||||
|
||||
return actorList;
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
//
|
||||
// Created by koncord on 25.08.17.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <components/openmw-mp/Base/BaseActor.hpp>
|
||||
#include "NetActor.hpp"
|
||||
|
||||
class LuaState;
|
||||
class Player;
|
||||
|
||||
class Actor: public NetActor
|
||||
{
|
||||
friend class ActorController;
|
||||
public:
|
||||
static void Init(LuaState &lua);
|
||||
public:
|
||||
Actor();
|
||||
std::string getRefId() const;
|
||||
void setRefId(const std::string &refId);
|
||||
|
||||
int getRefNumIndex() const;
|
||||
void setRefNumIndex(int refNumIndex);
|
||||
int getMpNum() const;
|
||||
void setMpNum(int mpNum);
|
||||
bool doesHavePosition() const; // ????
|
||||
bool doesHaveStatsDynamic() const; // ????
|
||||
|
||||
std::shared_ptr<mwmp::BaseActor> actor;
|
||||
};
|
||||
|
||||
class ActorController
|
||||
{
|
||||
public:
|
||||
static void Init(LuaState &lua);
|
||||
public:
|
||||
|
||||
ActorController();
|
||||
~ActorController();
|
||||
|
||||
std::shared_ptr<Actor> createActor();
|
||||
void sendActors(std::shared_ptr<Player> player, std::vector<std::shared_ptr<Actor>> actors, bool sendToAll = false);
|
||||
void sendList(std::shared_ptr<Player> player, std::vector<std::shared_ptr<Actor>> actors, bool sendToAll = false);
|
||||
|
||||
void requestList(std::shared_ptr<Player> player);
|
||||
|
||||
std::vector<std::shared_ptr<Actor>> getActors(std::shared_ptr<Player> player);
|
||||
|
||||
private:
|
||||
mwmp::BaseActorList actorList;
|
||||
};
|
||||
|
||||
|
@ -0,0 +1,68 @@
|
||||
//
|
||||
// Created by koncord on 15.08.17.
|
||||
//
|
||||
|
||||
#include "Books.hpp"
|
||||
|
||||
#include <components/openmw-mp/NetworkMessages.hpp>
|
||||
#include "Script/LuaState.hpp"
|
||||
#include "Player.hpp"
|
||||
#include "Networking.hpp"
|
||||
|
||||
void Books::Init(LuaState &lua)
|
||||
{
|
||||
lua.getState()->new_usertype<Books>("Books",
|
||||
"addBook", &Books::addBook,
|
||||
"getBookId", &Books::getBookId,
|
||||
"getChanges", &Books::getChanges,
|
||||
"reset", &Books::reset
|
||||
);
|
||||
}
|
||||
|
||||
Books::Books(Player *player) : player(player), changed(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Books::~Books()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Books::addBook(const std::string &bookId)
|
||||
{
|
||||
if (!changed)
|
||||
reset();
|
||||
player->bookChanges.books.push_back({bookId});
|
||||
changed = true;
|
||||
}
|
||||
|
||||
std::string Books::getBookId(unsigned i) const
|
||||
{
|
||||
if (i >= player->bookChanges.count)
|
||||
return "invalid";
|
||||
|
||||
return player->bookChanges.books.at(i).bookId;
|
||||
}
|
||||
|
||||
unsigned Books::getChanges() const
|
||||
{
|
||||
return player->bookChanges.count;
|
||||
}
|
||||
|
||||
void Books::reset()
|
||||
{
|
||||
player->bookChanges.books.clear();
|
||||
}
|
||||
|
||||
void Books::update()
|
||||
{
|
||||
if (!changed)
|
||||
return;
|
||||
changed = false;
|
||||
|
||||
auto packet = mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_BOOK);
|
||||
|
||||
packet->setPlayer(player);
|
||||
packet->Send(/*toOthers*/ false);
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
//
|
||||
// Created by koncord on 15.08.17.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
class LuaState;
|
||||
class Player;
|
||||
|
||||
class Books
|
||||
{
|
||||
public:
|
||||
static void Init(LuaState &lua);
|
||||
public:
|
||||
|
||||
explicit Books(Player *player);
|
||||
~Books();
|
||||
|
||||
void addBook(const std::string &bookId);
|
||||
std::string getBookId(unsigned i) const;
|
||||
unsigned getChanges() const;
|
||||
void reset();
|
||||
|
||||
void update();
|
||||
private:
|
||||
Player *player;
|
||||
bool changed;
|
||||
};
|
||||
|
||||
|
@ -0,0 +1,30 @@
|
||||
//
|
||||
// Created by koncord on 25.08.17.
|
||||
//
|
||||
|
||||
#include "CellState.hpp"
|
||||
|
||||
#include "Script/LuaState.hpp"
|
||||
|
||||
void CellState::Init(LuaState &lua)
|
||||
{
|
||||
lua.getState()->new_usertype<CellState>("CellState",
|
||||
"type", sol::property(&CellState::getStateType),
|
||||
"description", sol::property(&CellState::getDescription)
|
||||
);
|
||||
}
|
||||
|
||||
CellState::CellState(mwmp::CellState state) : state(state)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int CellState::getStateType() const
|
||||
{
|
||||
return state.type;
|
||||
}
|
||||
|
||||
std::string CellState::getDescription() const
|
||||
{
|
||||
return state.cell.getDescription();
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
//
|
||||
// Created by koncord on 25.08.17.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <components/openmw-mp/Base/BasePlayer.hpp>
|
||||
|
||||
class LuaState;
|
||||
|
||||
class CellState
|
||||
{
|
||||
public:
|
||||
static void Init(LuaState &lua);
|
||||
|
||||
explicit CellState(mwmp::CellState state);
|
||||
public:
|
||||
int getStateType() const;
|
||||
std::string getDescription() const;
|
||||
|
||||
private:
|
||||
mwmp::CellState state;
|
||||
};
|
@ -0,0 +1,99 @@
|
||||
//
|
||||
// Created by koncord on 25.08.17.
|
||||
//
|
||||
|
||||
#include "Cells.hpp"
|
||||
|
||||
#include <components/openmw-mp/NetworkMessages.hpp>
|
||||
#include "Script/LuaState.hpp"
|
||||
#include "NetActor.hpp"
|
||||
#include "Networking.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
void Cells::Init(LuaState &lua)
|
||||
{
|
||||
lua.getState()->new_usertype<Cells>("Cells",
|
||||
"cell", sol::property(&Cells::getCell, &Cells::setCell),
|
||||
"getExterior", &Cells::getExterior,
|
||||
"setExterior", &Cells::setExterior,
|
||||
"getRegion", &Cells::getRegion,
|
||||
|
||||
"isExterior", &Cells::isExterior,
|
||||
"isChangingRegion", &Cells::isChangingRegion
|
||||
);
|
||||
}
|
||||
|
||||
Cells::Cells(NetActor *netActor) : netActor(netActor), changedCell(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Cells::~Cells()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Cells::update()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::string Cells::getCell() const
|
||||
{
|
||||
return netActor->getNetCreature()->cell.getDescription();
|
||||
}
|
||||
|
||||
void Cells::setCell(const std::string &cellDescription)
|
||||
{
|
||||
/*LOG_MESSAGE_SIMPLE(Log::LOG_INFO, "Script is moving %s from %s to %s", netActor->getNetCreature()->npc.mName.c_str(),
|
||||
netActor->getNetCreature()->cell.getDescription().c_str(), cellDescription.c_str());*/
|
||||
|
||||
netActor->getNetCreature()->cell = Utils::getCellFromDescription(cellDescription);
|
||||
changedCell = true;
|
||||
}
|
||||
|
||||
std::tuple<int, int> Cells::getExterior() const
|
||||
{
|
||||
return make_tuple(netActor->getNetCreature()->cell.mData.mX, netActor->getNetCreature()->cell.mData.mY);
|
||||
}
|
||||
|
||||
void Cells::setExterior(int x, int y)
|
||||
{
|
||||
/*LOG_MESSAGE_SIMPLE(Log::LOG_INFO, "Script is moving %s from %s to %i,%i", netActor->getNetCreature()->npc.mName.c_str(),
|
||||
netActor->getNetCreature()->cell.getDescription().c_str(), x, y);*/
|
||||
|
||||
// If the player is currently in an interior, turn off the interior flag from the cell
|
||||
if (!netActor->getNetCreature()->cell.isExterior())
|
||||
netActor->getNetCreature()->cell.mData.mFlags &= ~ESM::Cell::Interior;
|
||||
|
||||
netActor->getNetCreature()->cell.mData.mX = x;
|
||||
netActor->getNetCreature()->cell.mData.mY = y;
|
||||
changedCell = true;
|
||||
}
|
||||
|
||||
bool Cells::isExterior() const
|
||||
{
|
||||
return netActor->getNetCreature()->cell.isExterior();
|
||||
}
|
||||
|
||||
bool Cells::isChangingRegion() const
|
||||
{
|
||||
return netActor->getNetCreature()->isChangingRegion;
|
||||
}
|
||||
|
||||
std::string Cells::getRegion() const
|
||||
{
|
||||
return netActor->getNetCreature()->cell.mRegion;
|
||||
}
|
||||
|
||||
bool Cells::isChangedCell() const
|
||||
{
|
||||
return changedCell;
|
||||
}
|
||||
|
||||
void Cells::resetChangedCell()
|
||||
{
|
||||
changedCell = false;
|
||||
}
|
||||
|
@ -0,0 +1,43 @@
|
||||
//
|
||||
// Created by koncord on 25.08.17.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <components/openmw-mp/Base/BasePlayer.hpp>
|
||||
|
||||
class LuaState;
|
||||
class NetActor;
|
||||
|
||||
class Cells
|
||||
{
|
||||
public:
|
||||
static void Init(LuaState &lua);
|
||||
public:
|
||||
explicit Cells(NetActor *netActor);
|
||||
~Cells();
|
||||
|
||||
void update();
|
||||
|
||||
std::string getCell() const;
|
||||
void setCell(const std::string &cellDescription);
|
||||
|
||||
std::tuple<int, int> getExterior() const;
|
||||
void setExterior(int x, int y);
|
||||
|
||||
bool isExterior() const;
|
||||
bool isChangingRegion() const;
|
||||
|
||||
std::string getRegion() const;
|
||||
|
||||
bool isChangedCell() const;
|
||||
void resetChangedCell();
|
||||
|
||||
private:
|
||||
NetActor *netActor;
|
||||
bool changedCell;
|
||||
};
|
||||
|
||||
|
@ -0,0 +1,153 @@
|
||||
//
|
||||
// Created by koncord on 12.08.17.
|
||||
//
|
||||
|
||||
#include "CharClass.hpp"
|
||||
|
||||
#include <components/openmw-mp/NetworkMessages.hpp>
|
||||
#include <apps/openmw-mp/Script/LuaState.hpp>
|
||||
#include "Player.hpp"
|
||||
#include "Networking.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
void CharClass::Init(LuaState &lua)
|
||||
{
|
||||
lua.getState()->new_usertype<CharClass>("Class",
|
||||
//"__gc", sol::destructor(deleter),
|
||||
"default", sol::property(&CharClass::getDefault, &CharClass::setDefault),
|
||||
"isDefault", &CharClass::isDefault,
|
||||
|
||||
"name", sol::property(&CharClass::getName, &CharClass::setName),
|
||||
"description", sol::property(&CharClass::getDesc, &CharClass::setDesc),
|
||||
"specialization",
|
||||
sol::property(&CharClass::getSpecialization, &CharClass::setSpecialization),
|
||||
|
||||
"getMajorAttributes", &CharClass::getMajorAttributes,
|
||||
"setMajorAttributes", &CharClass::setMajorAttributes,
|
||||
|
||||
"getMinorSkills", &CharClass::getMinorSkills,
|
||||
"setMinorSkills", &CharClass::setMinorSkills,
|
||||
|
||||
"getMajorSkills", &CharClass::getMajorSkills,
|
||||
"setMajorSkills", &CharClass::setMajorSkills
|
||||
);
|
||||
}
|
||||
|
||||
CharClass::CharClass(Player *player) : player(player), changed(false)
|
||||
{
|
||||
printf("CharClass::CharClass()\n");
|
||||
}
|
||||
|
||||
CharClass::~CharClass()
|
||||
{
|
||||
printf("CharClass::~CharClass()\n");
|
||||
}
|
||||
|
||||
string CharClass::getDefault() const
|
||||
{
|
||||
return player->charClass.mId;
|
||||
}
|
||||
|
||||
void CharClass::setDefault(const string &className)
|
||||
{
|
||||
player->charClass.mId = className;
|
||||
changed = true;
|
||||
printf("CharClass::setDefault()\n");
|
||||
}
|
||||
|
||||
bool CharClass::isDefault() const
|
||||
{
|
||||
return player->charClass.mId.empty();
|
||||
}
|
||||
|
||||
void CharClass::setName(const string &className)
|
||||
{
|
||||
player->charClass.mName = className;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
string CharClass::getName() const
|
||||
{
|
||||
return player->charClass.mName;
|
||||
}
|
||||
|
||||
std::string CharClass::getDesc() const
|
||||
{
|
||||
return player->charClass.mDescription;
|
||||
}
|
||||
|
||||
void CharClass::setDesc(const string &desc)
|
||||
{
|
||||
player->charClass.mDescription = desc;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
std::tuple<int, int> CharClass::getMajorAttributes() const
|
||||
{
|
||||
const auto &data = player->charClass.mData;
|
||||
return make_tuple(data.mAttribute[0], data.mAttribute[1]);
|
||||
}
|
||||
|
||||
void CharClass::setMajorAttributes(int first, int second)
|
||||
{
|
||||
auto &data = player->charClass.mData;
|
||||
data.mAttribute[0] = first;
|
||||
data.mAttribute[1] = second;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
int CharClass::getSpecialization() const
|
||||
{
|
||||
return player->charClass.mData.mSpecialization;
|
||||
}
|
||||
|
||||
void CharClass::setSpecialization(int spec)
|
||||
{
|
||||
auto &data = player->charClass.mData;
|
||||
data.mSpecialization = spec;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
std::tuple<int, int, int, int> CharClass::getMinorSkills() const
|
||||
{
|
||||
const auto &data = player->charClass.mData;
|
||||
return make_tuple( data.mSkills[0][0], data.mSkills[1][0], data.mSkills[2][0], data.mSkills[3][0]);
|
||||
}
|
||||
|
||||
void CharClass::setMinorSkills(int fisrt, int second, int third, int fourth)
|
||||
{
|
||||
auto &data = player->charClass.mData;
|
||||
data.mSkills[0][0] = fisrt;
|
||||
data.mSkills[1][0] = second;
|
||||
data.mSkills[2][0] = third;
|
||||
data.mSkills[3][0] = fourth;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
std::tuple<int, int, int, int> CharClass::getMajorSkills() const
|
||||
{
|
||||
const auto &data = player->charClass.mData;
|
||||
return make_tuple( data.mSkills[0][1], data.mSkills[1][1], data.mSkills[2][1], data.mSkills[3][1]);
|
||||
}
|
||||
|
||||
void CharClass::setMajorSkills(int fisrt, int second, int third, int fourth)
|
||||
{
|
||||
auto &data = player->charClass.mData;
|
||||
data.mSkills[0][1] = fisrt;
|
||||
data.mSkills[1][1] = second;
|
||||
data.mSkills[2][1] = third;
|
||||
data.mSkills[3][1] = fourth;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
void CharClass::update()
|
||||
{
|
||||
if (!changed)
|
||||
return;
|
||||
changed = false;
|
||||
printf("CharClass::update()\n");
|
||||
auto packet = mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_CHARCLASS);
|
||||
packet->setPlayer(player);
|
||||
packet->Send(false);
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
//
|
||||
// Created by koncord on 12.08.17.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
|
||||
class LuaState;
|
||||
class Player;
|
||||
|
||||
class CharClass
|
||||
{
|
||||
public:
|
||||
static void Init(LuaState &lua);
|
||||
|
||||
public:
|
||||
explicit CharClass(Player *player);
|
||||
~CharClass();
|
||||
void update();
|
||||
|
||||
std::string getDefault() const;
|
||||
void setDefault(const std::string &className);
|
||||
bool isDefault() const;
|
||||
|
||||
std::string getName() const;
|
||||
void setName(const std::string &className);
|
||||
|
||||
std::string getDesc() const;
|
||||
void setDesc(const std::string &desc);
|
||||
|
||||
std::tuple<int, int> getMajorAttributes() const;
|
||||
void setMajorAttributes(int first, int second);
|
||||
|
||||
int getSpecialization() const;
|
||||
void setSpecialization(int spec);
|
||||
|
||||
std::tuple<int, int, int, int> getMinorSkills() const;
|
||||
void setMinorSkills(int fisrt, int second, int third, int fourth);
|
||||
|
||||
std::tuple<int, int, int, int> getMajorSkills() const;
|
||||
void setMajorSkills(int fisrt, int second, int third, int fourth);
|
||||
private:
|
||||
// not controlled pointer
|
||||
Player *player;
|
||||
bool changed;
|
||||
};
|
||||
|
||||
|
@ -0,0 +1,62 @@
|
||||
//
|
||||
// Created by koncord on 15.08.17.
|
||||
//
|
||||
|
||||
#include "Dialogue.hpp"
|
||||
|
||||
#include <components/openmw-mp/NetworkMessages.hpp>
|
||||
#include "Script/LuaState.hpp"
|
||||
#include "Player.hpp"
|
||||
#include "Networking.hpp"
|
||||
|
||||
void Dialogue::Init(LuaState &lua)
|
||||
{
|
||||
lua.getState()->new_usertype<Dialogue>("Dialogue",
|
||||
"addTopic", &Dialogue::addTopic,
|
||||
"getTopicId", &Dialogue::getTopicId,
|
||||
"getChanges", &Dialogue::getChanges,
|
||||
"reset", &Dialogue::reset);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Dialogue::Dialogue(Player *player) : player(player), changed(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
void Dialogue::reset()
|
||||
{
|
||||
player->topicChanges.topics.clear();
|
||||
}
|
||||
|
||||
void Dialogue::update()
|
||||
{
|
||||
if (!changed)
|
||||
return;
|
||||
changed = false;
|
||||
|
||||
auto packet = mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_TOPIC);
|
||||
|
||||
packet->setPlayer(player);
|
||||
packet->Send(/*toOthers*/ false);
|
||||
}
|
||||
|
||||
void Dialogue::addTopic(const std::string &topicId)
|
||||
{
|
||||
if (!changed)
|
||||
reset();
|
||||
changed = true;
|
||||
player->topicChanges.topics.push_back({topicId});
|
||||
}
|
||||
|
||||
std::string Dialogue::getTopicId(unsigned int i) const
|
||||
{
|
||||
return player->topicChanges.topics.at(i).topicId;
|
||||
}
|
||||
|
||||
unsigned int Dialogue::getChanges() const
|
||||
{
|
||||
return player->topicChanges.count;
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
//
|
||||
// Created by koncord on 15.08.17.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
class LuaState;
|
||||
class Player;
|
||||
|
||||
class Dialogue
|
||||
{
|
||||
public:
|
||||
static void Init(LuaState &lua);
|
||||
public:
|
||||
explicit Dialogue(Player *player);
|
||||
|
||||
void addTopic(const std::string &topicId);
|
||||
std::string getTopicId(unsigned int i) const;
|
||||
unsigned int getChanges() const;
|
||||
|
||||
void reset();
|
||||
void update();
|
||||
private:
|
||||
Player *player;
|
||||
bool changed;
|
||||
};
|
||||
|
||||
|
@ -0,0 +1,154 @@
|
||||
//
|
||||
// Created by koncord on 17.08.17.
|
||||
//
|
||||
|
||||
#include <components/openmw-mp/NetworkMessages.hpp>
|
||||
#include "Factions.hpp"
|
||||
|
||||
#include "Player.hpp"
|
||||
#include "Script/LuaState.hpp"
|
||||
#include "Networking.hpp"
|
||||
|
||||
void Factions::Init(LuaState &lua)
|
||||
{
|
||||
lua.getState()->new_usertype<Factions>("Factions",
|
||||
"addFaction", &Factions::addFaction,
|
||||
"changesAction", sol::property(&Factions::getFactionChangesAction, &Factions::setFactionChangesAction),
|
||||
"getFaction", &Factions::getFaction,
|
||||
"setFaction", &Factions::setFaction,
|
||||
"clear", &Factions::clear,
|
||||
"size", &Factions::size
|
||||
|
||||
);
|
||||
/*"InitializeFactionChanges", FactionFunctions::InitializeFactionChanges,
|
||||
"GetFactionChangesSize", FactionFunctions::GetFactionChangesSize,
|
||||
"GetFactionChangesAction", FactionFunctions::GetFactionChangesAction,
|
||||
"GetFactionId", FactionFunctions::GetFactionId,
|
||||
"GetFactionRank", FactionFunctions::GetFactionRank,
|
||||
"GetFactionExpulsionState", FactionFunctions::GetFactionExpulsionState,
|
||||
"GetFactionReputation", FactionFunctions::GetFactionReputation,
|
||||
"SetFactionChangesAction", FactionFunctions::SetFactionChangesAction,
|
||||
"SetFactionId", FactionFunctions::SetFactionId,
|
||||
"SetFactionRank", FactionFunctions::SetFactionRank,
|
||||
"SetFactionExpulsionState", FactionFunctions::SetFactionExpulsionState,
|
||||
"SetFactionReputation", FactionFunctions::SetFactionReputation,
|
||||
"AddFaction", FactionFunctions::AddFaction,
|
||||
"SendFactionChanges", FactionFunctions::SendFactionChanges*/
|
||||
}
|
||||
|
||||
Factions::Factions(Player *player): player(player), changed(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Factions::~Factions()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Factions::update()
|
||||
{
|
||||
if (!changed)
|
||||
return;
|
||||
changed = false;
|
||||
|
||||
auto packet =mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_FACTION);
|
||||
packet->setPlayer(player);
|
||||
packet->Send(/*toOthers*/ false);
|
||||
clear();
|
||||
}
|
||||
|
||||
int Factions::getFactionChangesAction() const
|
||||
{
|
||||
return player->factionChanges.action;
|
||||
}
|
||||
|
||||
void Factions::setFactionChangesAction(int action)
|
||||
{
|
||||
player->factionChanges.action = action;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
void Factions::addFaction(Faction faction)
|
||||
{
|
||||
player->factionChanges.factions.push_back(faction.faction);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
|
||||
Faction Factions::getFaction(int id) const
|
||||
{
|
||||
return Faction(player->factionChanges.factions.at(id));
|
||||
}
|
||||
|
||||
void Factions::setFaction(int id, Faction faction)
|
||||
{
|
||||
player->factionChanges.factions.at(id) = faction.faction;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
void Factions::clear()
|
||||
{
|
||||
player->factionChanges.factions.clear();
|
||||
changed = true;
|
||||
}
|
||||
|
||||
size_t Factions::size() const
|
||||
{
|
||||
return player->factionChanges.factions.size();
|
||||
}
|
||||
|
||||
void Faction::Init(LuaState &lua)
|
||||
{
|
||||
lua.getState()->new_usertype<Faction>("Faction",
|
||||
"factionId", sol::property(&Faction::getFactionId, &Faction::setFactionId),
|
||||
"rank", sol::property(&Faction::getFactionRank, &Faction::setFactionRank),
|
||||
"isExpelled", sol::property(&Faction::getFactionExpulsionState, &Faction::setFactionExpulsionState),
|
||||
"reputation", sol::property(&Faction::getFactionReputation, &Faction::setFactionReputation)
|
||||
);
|
||||
}
|
||||
|
||||
Faction::Faction(mwmp::Faction &faction): faction(faction)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::string Faction::getFactionId() const
|
||||
{
|
||||
return faction.factionId;
|
||||
}
|
||||
|
||||
void Faction::setFactionId(const std::string &factionId)
|
||||
{
|
||||
faction.factionId = factionId;
|
||||
}
|
||||
|
||||
int Faction::getFactionRank() const
|
||||
{
|
||||
return faction.rank;
|
||||
}
|
||||
|
||||
void Faction::setFactionRank(unsigned int rank)
|
||||
{
|
||||
faction.rank = rank;
|
||||
}
|
||||
|
||||
bool Faction::getFactionExpulsionState() const
|
||||
{
|
||||
return faction.isExpelled;
|
||||
}
|
||||
|
||||
void Faction::setFactionExpulsionState(bool expulsionState)
|
||||
{
|
||||
faction.isExpelled = expulsionState;
|
||||
}
|
||||
|
||||
int Faction::getFactionReputation() const
|
||||
{
|
||||
return faction.reputation;
|
||||
}
|
||||
|
||||
void Faction::setFactionReputation(int reputation)
|
||||
{
|
||||
faction.reputation = reputation;
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
//
|
||||
// Created by koncord on 17.08.17.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <components/openmw-mp/Base/BasePlayer.hpp>
|
||||
|
||||
class LuaState;
|
||||
class Player;
|
||||
|
||||
class Faction
|
||||
{
|
||||
friend class Factions;
|
||||
public:
|
||||
static void Init(LuaState &lua);
|
||||
public:
|
||||
explicit Faction(mwmp::Faction &faction);
|
||||
|
||||
std::string getFactionId() const;
|
||||
void setFactionId(const std::string &factionId);
|
||||
|
||||
int getFactionRank() const;
|
||||
void setFactionRank(unsigned int rank);
|
||||
|
||||
bool getFactionExpulsionState() const;
|
||||
void setFactionExpulsionState(bool expulsionState);
|
||||
|
||||
int getFactionReputation() const;
|
||||
void setFactionReputation(int reputation);
|
||||
|
||||
mwmp::Faction faction;
|
||||
};
|
||||
|
||||
class Factions
|
||||
{
|
||||
public:
|
||||
static void Init(LuaState &lua);
|
||||
public:
|
||||
explicit Factions(Player *player);
|
||||
~Factions();
|
||||
|
||||
void update();
|
||||
|
||||
int getFactionChangesAction() const;
|
||||
void setFactionChangesAction(int action);
|
||||
|
||||
void addFaction(Faction faction);
|
||||
Faction getFaction(int id) const;
|
||||
void setFaction(int id, Faction faction);
|
||||
size_t size() const;
|
||||
void clear();
|
||||
|
||||
private:
|
||||
mwmp::Faction tempFaction;
|
||||
Player *player;
|
||||
bool changed;
|
||||
};
|
@ -0,0 +1,100 @@
|
||||
//
|
||||
// Created by koncord on 15.08.17.
|
||||
//
|
||||
|
||||
#include <components/openmw-mp/NetworkMessages.hpp>
|
||||
#include "GUI.hpp"
|
||||
#include "Player.hpp"
|
||||
#include "Networking.hpp"
|
||||
|
||||
void GUI::Init(LuaState &lua)
|
||||
{
|
||||
lua.getState()->new_usertype<GUI>("GUI",
|
||||
"messageBox", &GUI::messageBox,
|
||||
"customMessageBox", &GUI::customMessageBox,
|
||||
"inputDialog", &GUI::inputDialog,
|
||||
"passwordDialog", &GUI::passwordDialog,
|
||||
"listBox", &GUI::listBox,
|
||||
"setMapVisibility", &GUI::setMapVisibility,
|
||||
"setMapVisibilityAll", &GUI::setMapVisibilityAll
|
||||
);
|
||||
}
|
||||
|
||||
GUI::GUI(Player *player): player(player), changed(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
GUI::~GUI()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void GUI::update()
|
||||
{
|
||||
if (!changed)
|
||||
return;
|
||||
changed = false;
|
||||
|
||||
auto packet = mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_GUI_MESSAGEBOX);
|
||||
packet->setPlayer(player);
|
||||
packet->Send(false);
|
||||
}
|
||||
|
||||
void GUI::messageBox(int id, const char *label)
|
||||
{
|
||||
player->guiMessageBox.id = id;
|
||||
player->guiMessageBox.label = label;
|
||||
player->guiMessageBox.type = Player::GUIMessageBox::MessageBox;
|
||||
|
||||
changed = true;
|
||||
}
|
||||
|
||||
void GUI::customMessageBox(int id, const char *label, const char *buttons)
|
||||
{
|
||||
player->guiMessageBox.id = id;
|
||||
player->guiMessageBox.label = label;
|
||||
player->guiMessageBox.buttons = buttons;
|
||||
player->guiMessageBox.type = Player::GUIMessageBox::CustomMessageBox;
|
||||
|
||||
changed = true;
|
||||
}
|
||||
|
||||
void GUI::inputDialog(int id, const char *label)
|
||||
{
|
||||
player->guiMessageBox.id = id;
|
||||
player->guiMessageBox.label = label;
|
||||
player->guiMessageBox.type = Player::GUIMessageBox::InputDialog;
|
||||
|
||||
changed = true;
|
||||
}
|
||||
|
||||
void GUI::passwordDialog(int id, const char *label, const char *note)
|
||||
{
|
||||
player->guiMessageBox.id = id;
|
||||
player->guiMessageBox.label = label;
|
||||
player->guiMessageBox.note = note;
|
||||
player->guiMessageBox.type = Player::GUIMessageBox::PasswordDialog;
|
||||
|
||||
changed = true;
|
||||
}
|
||||
|
||||
void GUI::listBox(int id, const char *label, const char *items)
|
||||
{
|
||||
player->guiMessageBox.id = id;
|
||||
player->guiMessageBox.label = label;
|
||||
player->guiMessageBox.data = items;
|
||||
player->guiMessageBox.type = Player::GUIMessageBox::ListBox;
|
||||
|
||||
changed = true;
|
||||
}
|
||||
|
||||
void GUI::setMapVisibility(unsigned short targetPID, unsigned short affectedPID, unsigned short state)
|
||||
{
|
||||
LOG_MESSAGE(Log::LOG_WARN, "stub");
|
||||
}
|
||||
|
||||
void GUI::setMapVisibilityAll(unsigned short targetPID, unsigned short state)
|
||||
{
|
||||
LOG_MESSAGE(Log::LOG_WARN, "stub");
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
//
|
||||
// Created by koncord on 15.08.17.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
class LuaState;
|
||||
class Player;
|
||||
|
||||
class GUI
|
||||
{
|
||||
public:
|
||||
static void Init(LuaState &lua);
|
||||
public:
|
||||
explicit GUI(Player *player);
|
||||
~GUI();
|
||||
|
||||
void update();
|
||||
|
||||
void messageBox(int id, const char *label);
|
||||
|
||||
void customMessageBox(int id, const char *label, const char *buttons);
|
||||
void inputDialog(int id, const char *label);
|
||||
void passwordDialog(int id, const char *label, const char *note);
|
||||
|
||||
void listBox(int id, const char *label, const char *items);
|
||||
|
||||
//state 0 - disallow, 1 - allow
|
||||
void setMapVisibility(unsigned short targetPID, unsigned short affectedPID, unsigned short state);
|
||||
void setMapVisibilityAll(unsigned short targetPID, unsigned short state);
|
||||
private:
|
||||
Player *player;
|
||||
bool changed;
|
||||
};
|
||||
|
||||
|
@ -0,0 +1,164 @@
|
||||
//
|
||||
// Created by koncord on 12.08.17.
|
||||
//
|
||||
|
||||
#include "Inventory.hpp"
|
||||
#include <components/openmw-mp/NetworkMessages.hpp>
|
||||
#include <apps/openmw-mp/Script/LuaState.hpp>
|
||||
#include <apps/openmw/mwworld/inventorystore.hpp>
|
||||
#include <components/misc/stringops.hpp>
|
||||
#include "NetActor.hpp"
|
||||
#include "Networking.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
void Inventory::Init(LuaState &lua)
|
||||
{
|
||||
lua.getState()->new_usertype<Inventory>("Inventory",
|
||||
"getInventoryChangesSize", &Inventory::getChangesSize,
|
||||
"addItem", &Inventory::addItem,
|
||||
"removeItem", &Inventory::removeItem,
|
||||
"getInventoryItem", &Inventory::getInventoryItem,
|
||||
|
||||
"equipItem", &Inventory::equipItem,
|
||||
"unequipItem", &Inventory::unequipItem,
|
||||
"hasItemEquipped", &Inventory::hasItemEquipped,
|
||||
"getEquipmentItem", &Inventory::getEquipmentItem
|
||||
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
Inventory::Inventory(NetActor *actor) : netActor(actor), equipmentChanged(false), inventoryChanged(0)
|
||||
{
|
||||
printf("Inventory::Inventory()\n");
|
||||
}
|
||||
|
||||
Inventory::~Inventory()
|
||||
{
|
||||
printf("Inventory::~Inventory()\n");
|
||||
}
|
||||
|
||||
void Inventory::update()
|
||||
{
|
||||
printf("Inventory::update()");
|
||||
/*if (equipmentChanged)
|
||||
{
|
||||
auto packet = mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_EQUIPMENT);
|
||||
packet->setPlayer(netActor->getNetCreature());
|
||||
packet->Send(false);
|
||||
packet->Send(true);
|
||||
}
|
||||
|
||||
if (inventoryChanged != 0)
|
||||
{
|
||||
auto packet = mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_EQUIPMENT);
|
||||
packet->setPlayer(netActor->getNetCreature());
|
||||
packet->Send(false);
|
||||
}
|
||||
|
||||
equipmentChanged = false;
|
||||
inventoryChanged = 0;*/
|
||||
}
|
||||
|
||||
|
||||
void Inventory::InitializeInventoryChanges()
|
||||
{
|
||||
netActor->getNetCreature()->inventoryChanges.items.clear();
|
||||
netActor->getNetCreature()->inventoryChanges.action = mwmp::InventoryChanges::SET;
|
||||
}
|
||||
|
||||
int Inventory::getChangesSize() const
|
||||
{
|
||||
return netActor->getNetCreature()->inventoryChanges.count;
|
||||
}
|
||||
|
||||
void Inventory::equipItem(unsigned short slot, const std::string& refId, unsigned int count, int charge)
|
||||
{
|
||||
netActor->getNetCreature()->equipedItems[slot].refId = refId;
|
||||
netActor->getNetCreature()->equipedItems[slot].count = count;
|
||||
netActor->getNetCreature()->equipedItems[slot].charge = charge;
|
||||
equipmentChanged = true;
|
||||
}
|
||||
|
||||
void Inventory::unequipItem( unsigned short slot)
|
||||
{
|
||||
equipItem(slot, "", 0, -1);
|
||||
}
|
||||
|
||||
|
||||
void Inventory::addItem(const std::string &refId, unsigned int count, int charge)
|
||||
{
|
||||
if (inventoryChanged == mwmp::InventoryChanges::REMOVE)
|
||||
return;
|
||||
if (inventoryChanged == 0)
|
||||
InitializeInventoryChanges();
|
||||
|
||||
mwmp::Item item;
|
||||
item.refId = refId;
|
||||
item.count = count;
|
||||
item.charge = charge;
|
||||
|
||||
netActor->getNetCreature()->inventoryChanges.items.push_back(item);
|
||||
netActor->getNetCreature()->inventoryChanges.action = mwmp::InventoryChanges::ADD;
|
||||
inventoryChanged = netActor->getNetCreature()->inventoryChanges.action;
|
||||
}
|
||||
|
||||
void Inventory::removeItem(const std::string &refId, unsigned short count)
|
||||
{
|
||||
if (inventoryChanged == mwmp::InventoryChanges::ADD)
|
||||
return;
|
||||
if (inventoryChanged == 0)
|
||||
InitializeInventoryChanges();
|
||||
|
||||
mwmp::Item item;
|
||||
item.refId = refId;
|
||||
item.count = count;
|
||||
|
||||
netActor->getNetCreature()->inventoryChanges.items.push_back(item);
|
||||
netActor->getNetCreature()->inventoryChanges.action = mwmp::InventoryChanges::REMOVE;
|
||||
inventoryChanged = netActor->getNetCreature()->inventoryChanges.action;
|
||||
}
|
||||
|
||||
bool Inventory::hasItemEquipped(const std::string &refId) const
|
||||
{
|
||||
for (int slot = 0; slot < MWWorld::InventoryStore::Slots; slot++)
|
||||
if (Misc::StringUtils::ciEqual(netActor->getNetCreature()->equipedItems[slot].refId, refId))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
std::tuple<std::string, int, int> Inventory::getEquipmentItem(unsigned short slot) const
|
||||
{
|
||||
const auto &item = netActor->getNetCreature()->equipedItems[slot];
|
||||
return make_tuple(item.refId, item.count, item.charge);
|
||||
}
|
||||
|
||||
std::tuple<std::string, int, int> Inventory::getInventoryItem(unsigned int slot) const
|
||||
{
|
||||
const auto &item = netActor->getNetCreature()->inventoryChanges.items.at(slot);
|
||||
return make_tuple(item.refId, item.count, item.charge);
|
||||
}
|
||||
|
||||
void Inventory::resetEquipmentFlag()
|
||||
{
|
||||
equipmentChanged = false;
|
||||
}
|
||||
|
||||
bool Inventory::isEquipmentChanged()
|
||||
{
|
||||
return equipmentChanged;
|
||||
}
|
||||
|
||||
void Inventory::resetInventoryFlag()
|
||||
{
|
||||
inventoryChanged = 0;
|
||||
}
|
||||
|
||||
int Inventory::inventoryChangeType()
|
||||
{
|
||||
return inventoryChanged;
|
||||
}
|
||||
|
||||
|
||||
|
@ -0,0 +1,63 @@
|
||||
//
|
||||
// Created by koncord on 12.08.17.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
|
||||
class LuaState;
|
||||
class NetActor;
|
||||
|
||||
class Inventory
|
||||
{
|
||||
public:
|
||||
static void Init(LuaState &lua);
|
||||
bool isEquipmentChanged();
|
||||
void resetEquipmentFlag();
|
||||
int inventoryChangeType();
|
||||
void resetInventoryFlag();
|
||||
public:
|
||||
explicit Inventory(NetActor *netActor);
|
||||
~Inventory();
|
||||
void update();
|
||||
|
||||
//inventory
|
||||
int getChangesSize() const;
|
||||
void addItem(const std::string& refId, unsigned int count, int charge);
|
||||
void removeItem(const std::string& refId, unsigned short count);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param slot
|
||||
* @return refid, count, charge
|
||||
*/
|
||||
std::tuple<std::string,int, int> getInventoryItem(unsigned int slot) const;
|
||||
|
||||
|
||||
// equipment
|
||||
void equipItem(unsigned short slot, const std::string& refId, unsigned int count, int charge);
|
||||
void unequipItem(unsigned short slot);
|
||||
|
||||
bool hasItemEquipped(const std::string& refId) const;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param slot
|
||||
* @return refid, count, charge
|
||||
*/
|
||||
std::tuple<std::string,int, int> getEquipmentItem(unsigned short slot) const;
|
||||
|
||||
|
||||
private:
|
||||
void InitializeInventoryChanges();
|
||||
|
||||
private:
|
||||
// not controlled pointer
|
||||
NetActor *netActor;
|
||||
bool equipmentChanged;
|
||||
int inventoryChanged;
|
||||
};
|
||||
|
||||
|
@ -0,0 +1,98 @@
|
||||
//
|
||||
// Created by koncord on 25.08.17.
|
||||
//
|
||||
|
||||
#include "NetActor.hpp"
|
||||
|
||||
#include <components/openmw-mp/NetworkMessages.hpp>
|
||||
#include "Script/LuaState.hpp"
|
||||
//#include "Player.hpp"
|
||||
#include "Networking.hpp"
|
||||
#include <components/openmw-mp/Base/BaseNetCreature.hpp>
|
||||
|
||||
using namespace std;
|
||||
|
||||
NetActor::NetActor() : inventory(this), cellAPI(this)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void NetActor::resetUpdateFlags()
|
||||
{
|
||||
statsChanged = false;
|
||||
skillsChanged = false;
|
||||
attributesChanged = false;
|
||||
baseInfoChanged = false;
|
||||
positionChanged = false;
|
||||
}
|
||||
|
||||
std::tuple<float, float, float> NetActor::getPosition() const
|
||||
{
|
||||
return make_tuple(netCreature->position.pos[0], netCreature->position.pos[1], netCreature->position.pos[2]);
|
||||
}
|
||||
|
||||
void NetActor::setPosition(float x, float y, float z)
|
||||
{
|
||||
netCreature->position.pos[0] = x;
|
||||
netCreature->position.pos[1] = y;
|
||||
netCreature->position.pos[2] = z;
|
||||
positionChanged = true;
|
||||
}
|
||||
|
||||
std::tuple<float, float> NetActor::getRotation() const
|
||||
{
|
||||
return make_tuple(netCreature->position.rot[0], netCreature->position.rot[2]);
|
||||
}
|
||||
|
||||
void NetActor::setRotation(float x, float z)
|
||||
{
|
||||
netCreature->position.rot[0] = x;
|
||||
netCreature->position.rot[2] = z;
|
||||
positionChanged = true;
|
||||
}
|
||||
|
||||
std::tuple<float, float> NetActor::getHealth() const
|
||||
{
|
||||
return make_tuple(netCreature->creatureStats.mDynamic[0].mBase, netCreature->creatureStats.mDynamic[0].mCurrent);
|
||||
}
|
||||
|
||||
void NetActor::setHealth(float base, float current)
|
||||
{
|
||||
netCreature->creatureStats.mDynamic[0].mBase = base;
|
||||
netCreature->creatureStats.mDynamic[0].mCurrent = current;
|
||||
statsChanged = true;
|
||||
}
|
||||
|
||||
std::tuple<float, float> NetActor::getMagicka() const
|
||||
{
|
||||
return make_tuple(netCreature->creatureStats.mDynamic[1].mBase, netCreature->creatureStats.mDynamic[1].mCurrent);
|
||||
}
|
||||
|
||||
void NetActor::setMagicka(float base, float current)
|
||||
{
|
||||
netCreature->creatureStats.mDynamic[1].mBase = base;
|
||||
netCreature->creatureStats.mDynamic[1].mCurrent = current;
|
||||
statsChanged = true;
|
||||
}
|
||||
|
||||
std::tuple<float, float> NetActor::getFatigue() const
|
||||
{
|
||||
return make_tuple(netCreature->creatureStats.mDynamic[2].mBase, netCreature->creatureStats.mDynamic[2].mCurrent);
|
||||
}
|
||||
|
||||
void NetActor::setFatigue(float base, float current)
|
||||
{
|
||||
netCreature->creatureStats.mDynamic[2].mBase = base;
|
||||
netCreature->creatureStats.mDynamic[2].mCurrent = current;
|
||||
statsChanged = true;
|
||||
}
|
||||
|
||||
Inventory &NetActor::getInventory()
|
||||
{
|
||||
return inventory;
|
||||
}
|
||||
|
||||
Cells &NetActor::getCell()
|
||||
{
|
||||
return cellAPI;
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
//
|
||||
// Created by koncord on 25.08.17.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <RakNetTypes.h>
|
||||
#include <tuple>
|
||||
#include "Inventory.hpp"
|
||||
#include "Cells.hpp"
|
||||
|
||||
namespace mwmp
|
||||
{
|
||||
class BasePlayer;
|
||||
class BaseNetCreature;
|
||||
class BaseActor;
|
||||
}
|
||||
|
||||
class NetActor
|
||||
{
|
||||
public:
|
||||
NetActor();
|
||||
|
||||
void resetUpdateFlags();
|
||||
|
||||
/**
|
||||
*
|
||||
* @return x, y, z
|
||||
*/
|
||||
|
||||
std::tuple<float, float, float> getPosition() const;
|
||||
void setPosition(float x, float y, float z);
|
||||
|
||||
/**
|
||||
*
|
||||
* @return x, y
|
||||
*/
|
||||
std::tuple<float, float> getRotation() const;
|
||||
void setRotation(float x, float z);
|
||||
|
||||
/**
|
||||
*
|
||||
* @return base, current
|
||||
*/
|
||||
std::tuple<float, float> getHealth() const;
|
||||
void setHealth(float base, float current);
|
||||
|
||||
/**
|
||||
*
|
||||
* @return base, current
|
||||
*/
|
||||
std::tuple<float, float> getMagicka() const;
|
||||
void setMagicka(float base, float current);
|
||||
|
||||
/**
|
||||
*
|
||||
* @return base, current
|
||||
*/
|
||||
std::tuple<float, float> getFatigue() const;
|
||||
void setFatigue(float base, float current);
|
||||
|
||||
Inventory &getInventory();
|
||||
Cells &getCell();
|
||||
|
||||
mwmp::BaseNetCreature *getNetCreature() { return netCreature; }
|
||||
protected:
|
||||
bool statsChanged, attributesChanged, skillsChanged, baseInfoChanged, positionChanged;
|
||||
mwmp::BasePlayer *basePlayer;
|
||||
mwmp::BaseNetCreature *netCreature;
|
||||
|
||||
Inventory inventory;
|
||||
Cells cellAPI;
|
||||
};
|
||||
|
||||
|
@ -0,0 +1,466 @@
|
||||
//
|
||||
// Created by koncord on 26.08.17.
|
||||
//
|
||||
|
||||
#include <components/openmw-mp/NetworkMessages.hpp>
|
||||
#include "Object.hpp"
|
||||
#include "Player.hpp"
|
||||
#include "Networking.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
void Object::Init(LuaState &lua)
|
||||
{
|
||||
lua.getState()->new_usertype<Object>("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<float, float, float> 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<float, float, float> 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>("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<string, int, int> 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> player, shared_ptr<vector<shared_ptr<Object>>> objects) {
|
||||
return lua.getObjectCtrl().sendObjects(player, objects);
|
||||
});
|
||||
|
||||
objectCtrl.set_function("sendContainers", [&lua](shared_ptr<Player> player, shared_ptr<vector<shared_ptr<Container>>> objects) {
|
||||
return lua.getObjectCtrl().sendContainers(player, objects);
|
||||
});
|
||||
|
||||
objectCtrl.set_function("requestContainers", [&lua](shared_ptr<Player> player) {
|
||||
return lua.getObjectCtrl().requestContainers(player);
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
shared_ptr<vector<shared_ptr<Object>>> ObjectController::copyObjects(mwmp::BaseEvent &event)
|
||||
{
|
||||
auto objects = make_shared<vector<shared_ptr<Object>>>();
|
||||
|
||||
for(auto &obj : event.worldObjects)
|
||||
{
|
||||
auto object = new Object;
|
||||
object->copied = true;
|
||||
object->object = obj;
|
||||
objects->emplace_back(object);
|
||||
}
|
||||
return objects;
|
||||
}
|
||||
|
||||
shared_ptr<vector<shared_ptr<Container>>> ObjectController::copyContainers(mwmp::BaseEvent &event)
|
||||
{
|
||||
auto containers = make_shared<vector<shared_ptr<Container>>>();
|
||||
|
||||
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> player, shared_ptr<vector<shared_ptr<Object>>> objects)
|
||||
{
|
||||
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 = player->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> player, shared_ptr<vector<shared_ptr<Container>>> objects)
|
||||
{
|
||||
|
||||
mwmp::BaseEvent event;
|
||||
event.cell = player->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> 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);
|
||||
}
|
@ -0,0 +1,119 @@
|
||||
//
|
||||
// Created by koncord on 26.08.17.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <tuple>
|
||||
#include <components/openmw-mp/Base/BaseEvent.hpp>
|
||||
#include <memory>
|
||||
|
||||
class LuaState;
|
||||
class Player;
|
||||
|
||||
class BaseObject
|
||||
{
|
||||
public:
|
||||
BaseObject();
|
||||
std::string getRefId() const;
|
||||
void setRefId(const std::string &refId);
|
||||
|
||||
int getRefNum() const;
|
||||
void setRefNum(int refNum);
|
||||
|
||||
int getMpNum() const;
|
||||
void setMpNum(int mpNum);
|
||||
|
||||
//void setEventCell(const std::string &cellDescription);
|
||||
|
||||
|
||||
mwmp::WorldObject object;
|
||||
bool changedBase;
|
||||
bool copied;
|
||||
};
|
||||
|
||||
class Object : public BaseObject
|
||||
{
|
||||
public:
|
||||
static void Init(LuaState &lua);
|
||||
public:
|
||||
Object();
|
||||
~Object();
|
||||
|
||||
void update();
|
||||
|
||||
/**
|
||||
*
|
||||
* @return x, y, z
|
||||
*/
|
||||
|
||||
std::tuple<float, float, float> getPosition() const;
|
||||
void setPosition(float x, float y, float z);
|
||||
|
||||
/**
|
||||
*
|
||||
* @return x, y, z
|
||||
*/
|
||||
std::tuple<float, float, float> getRotation() const;
|
||||
void setRotation(float x, float y, float z);
|
||||
|
||||
int getCount() const;
|
||||
void setCount(int count);
|
||||
|
||||
int getCharge() const;
|
||||
void setCharge(int charge);
|
||||
|
||||
int getGoldValue() const;
|
||||
void setGoldValue(int gold);
|
||||
|
||||
float getScale() const;
|
||||
void setScale(float scale);
|
||||
|
||||
bool getState() const;
|
||||
void setState(bool state);
|
||||
|
||||
int getDoorState() const;
|
||||
void setDoorState(int state);
|
||||
|
||||
int getLockLevel() const;
|
||||
void setLockLevel(int locklevel);
|
||||
|
||||
void setDisarmState(bool state);
|
||||
void setMasterState(bool state);
|
||||
|
||||
bool changedDoorState, changedObjectState, changedObjectScale, changedObjectTrap, changedObjectLock,
|
||||
changedObjectDelete, changedObjectSpawn, changedObjectPlace;
|
||||
};
|
||||
|
||||
class Container : public BaseObject
|
||||
{
|
||||
public:
|
||||
static void Init(LuaState &lua);
|
||||
public:
|
||||
Container();
|
||||
|
||||
std::tuple<std::string, int, int> getItem(int i) const;
|
||||
void addItem(const std::string &refId, int count, int charge);
|
||||
|
||||
void setItem(int i, const std::string &refId, int count, int charge);
|
||||
int getActionCount(int i) const;
|
||||
|
||||
size_t size() const;
|
||||
bool changed;
|
||||
};
|
||||
|
||||
|
||||
class ObjectController
|
||||
{
|
||||
public:
|
||||
static void Init(LuaState &lua);
|
||||
public:
|
||||
|
||||
std::shared_ptr<std::vector<std::shared_ptr<Object>>> copyObjects(mwmp::BaseEvent &event);
|
||||
std::shared_ptr<std::vector<std::shared_ptr<Container>>> copyContainers(mwmp::BaseEvent &event);
|
||||
|
||||
void sendObjects(std::shared_ptr<Player> player, std::shared_ptr<std::vector<std::shared_ptr<Object>>> objects);
|
||||
void sendContainers(std::shared_ptr<Player> player, std::shared_ptr<std::vector<std::shared_ptr<Container>>> objects);
|
||||
|
||||
void requestContainers(std::shared_ptr<Player> player);
|
||||
};
|
@ -0,0 +1,113 @@
|
||||
//
|
||||
// Created by koncord on 12.08.17.
|
||||
//
|
||||
|
||||
#include "Players.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
Players::Store Players::store;
|
||||
|
||||
void Players::Init(LuaState &lua)
|
||||
{
|
||||
sol::table playersTable = lua.getState()->create_named_table("Players");
|
||||
playersTable.set_function("getByPID", &Players::getPlayerByPID);
|
||||
playersTable.set_function("getByGUID", &Players::getPlayerByGUID);
|
||||
playersTable.set_function("for_each", [](sol::function func)
|
||||
{
|
||||
for (shared_ptr<Player> player : store)
|
||||
func(player);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
std::shared_ptr<Player> Players::getPlayerByPID(int pid)
|
||||
{
|
||||
const auto &ls = store.get<ByID>();
|
||||
auto it = ls.find(pid);
|
||||
if (it != ls.end())
|
||||
return *it;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<Player> Players::getPlayerByGUID(RakNet::RakNetGUID guid)
|
||||
{
|
||||
const auto &ls = store.get<ByGUID>();
|
||||
auto it = ls.find(guid.g);
|
||||
if (it != ls.end())
|
||||
return *it;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<Player> Players::addPlayer(RakNet::RakNetGUID guid)
|
||||
{
|
||||
const int maxConnections = 65535;
|
||||
LOG_MESSAGE_SIMPLE(Log::LOG_INFO, "Creating new player with guid %lu", guid.g);
|
||||
|
||||
auto player = make_shared<Player>(guid);
|
||||
|
||||
unsigned short findPid = 0;
|
||||
const auto &ls = store.get<ByID>();
|
||||
for (; findPid < maxConnections; ++findPid) // find empty slot
|
||||
{
|
||||
auto it = ls.find(findPid);
|
||||
if (it == ls.end())
|
||||
break;
|
||||
}
|
||||
|
||||
if (findPid >= maxConnections)
|
||||
return nullptr;
|
||||
|
||||
LOG_APPEND(Log::LOG_INFO, "- Storing in slot %i", findPid);
|
||||
player->id = findPid;
|
||||
player->guid = guid;
|
||||
store.push_back(player);
|
||||
return player;
|
||||
}
|
||||
|
||||
void Players::deletePlayerByPID(int pid)
|
||||
{
|
||||
LOG_MESSAGE_SIMPLE(Log::LOG_INFO, "Marking player (pid %lu) to deleting", pid);
|
||||
auto &ls = store.get<ByID>();
|
||||
auto it = ls.find(pid);
|
||||
if (it != ls.end())
|
||||
{
|
||||
ls.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
void Players::deletePlayerByGUID(RakNet::RakNetGUID guid)
|
||||
{
|
||||
LOG_MESSAGE_SIMPLE(Log::LOG_INFO, "Marking player (guid %lu) to deleting", guid.g);
|
||||
auto &ls = store.get<ByGUID>();
|
||||
auto it = ls.find(guid.g);
|
||||
if (it != ls.end())
|
||||
{
|
||||
LOG_APPEND(Log::LOG_INFO, "- references: %d", it->use_count());
|
||||
ls.erase(it);
|
||||
LOG_APPEND(Log::LOG_INFO, "- references: %d", it->use_count());
|
||||
}
|
||||
}
|
||||
|
||||
void Players::for_each(std::function<void (std::shared_ptr<Player>)> func)
|
||||
{
|
||||
for (auto &player : store)
|
||||
func(player);
|
||||
}
|
||||
|
||||
Players::Store::const_iterator Players::begin()
|
||||
{
|
||||
return store.cbegin();
|
||||
}
|
||||
|
||||
Players::Store::const_iterator Players::end()
|
||||
{
|
||||
return store.cend();
|
||||
}
|
||||
|
||||
size_t Players::size()
|
||||
{
|
||||
return store.size();
|
||||
}
|
@ -0,0 +1,53 @@
|
||||
//
|
||||
// Created by koncord on 12.08.17.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <boost/multi_index_container.hpp>
|
||||
#include <boost/multi_index/ordered_index.hpp>
|
||||
#include <boost/multi_index/identity.hpp>
|
||||
#include <boost/multi_index/member.hpp>
|
||||
#include <boost/multi_index/global_fun.hpp>
|
||||
#include <boost/multi_index/mem_fun.hpp>
|
||||
#include <boost/multi_index/random_access_index.hpp>
|
||||
#include "Player.hpp"
|
||||
|
||||
class LuaState;
|
||||
|
||||
|
||||
class Players
|
||||
{
|
||||
public:
|
||||
static void Init(LuaState &lua);
|
||||
public:
|
||||
Players() = delete; // static class
|
||||
protected:
|
||||
|
||||
struct ByID {};
|
||||
struct ByGUID {};
|
||||
|
||||
public:
|
||||
typedef boost::multi_index_container<std::shared_ptr<Player>,
|
||||
boost::multi_index::indexed_by<
|
||||
boost::multi_index::random_access<>,
|
||||
boost::multi_index::ordered_unique<boost::multi_index::tag<ByGUID>, BOOST_MULTI_INDEX_CONST_MEM_FUN(Player, uint64_t, getGUID)>,
|
||||
boost::multi_index::ordered_unique<boost::multi_index::tag<ByID>, boost::multi_index::member<Player, unsigned short, &Player::id> >
|
||||
> > Store;
|
||||
|
||||
|
||||
static std::shared_ptr<Player> getPlayerByPID(int pid);
|
||||
static std::shared_ptr<Player> getPlayerByGUID(RakNet::RakNetGUID guid);
|
||||
static std::shared_ptr<Player> addPlayer(RakNet::RakNetGUID guid);
|
||||
static void deletePlayerByPID(int pid);
|
||||
static void deletePlayerByGUID(RakNet::RakNetGUID guid);
|
||||
static Store::const_iterator begin();
|
||||
static Store::const_iterator end();
|
||||
static size_t size();
|
||||
|
||||
static void for_each(std::function<void(std::shared_ptr<Player>)> func);
|
||||
|
||||
private:
|
||||
static Store store;
|
||||
};
|
||||
|
@ -0,0 +1,161 @@
|
||||
//
|
||||
// Created by koncord on 25.08.17.
|
||||
//
|
||||
|
||||
#include "Quests.hpp"
|
||||
|
||||
#include <components/openmw-mp/NetworkMessages.hpp>
|
||||
#include "Script/LuaState.hpp"
|
||||
#include "Player.hpp"
|
||||
#include "Networking.hpp"
|
||||
|
||||
void JournalItem::Init(LuaState &lua)
|
||||
{
|
||||
lua.getState()->new_usertype<JournalItem>("JournalItem",
|
||||
"quest", sol::property(&JournalItem::getQuest, &JournalItem::setQuest),
|
||||
"index", sol::property(&JournalItem::getIndex, &JournalItem::setIndex),
|
||||
"actorRefId", sol::property(&JournalItem::getActorRefId, &JournalItem::setActorRefId),
|
||||
"type", sol::property(&JournalItem::getType, &JournalItem::setType)
|
||||
);
|
||||
}
|
||||
|
||||
JournalItem::JournalItem(mwmp::JournalItem item) : item(item)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
JournalItem::~JournalItem()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::string JournalItem::getQuest() const
|
||||
{
|
||||
return item.quest;
|
||||
}
|
||||
|
||||
void JournalItem::setQuest(const std::string &quest)
|
||||
{
|
||||
item.quest = quest;
|
||||
}
|
||||
|
||||
int JournalItem::getIndex() const
|
||||
{
|
||||
return item.index;
|
||||
}
|
||||
|
||||
void JournalItem::setIndex(int index)
|
||||
{
|
||||
item.index = index;
|
||||
}
|
||||
|
||||
int JournalItem::getType() const
|
||||
{
|
||||
return item.type;
|
||||
}
|
||||
|
||||
void JournalItem::setType(int type)
|
||||
{
|
||||
item.type = type;
|
||||
}
|
||||
|
||||
std::string JournalItem::getActorRefId() const
|
||||
{
|
||||
return item.actorRefId;
|
||||
}
|
||||
|
||||
void JournalItem::setActorRefId(const std::string &refid)
|
||||
{
|
||||
item.actorRefId = refid;
|
||||
}
|
||||
|
||||
void Quests::Init(LuaState &lua)
|
||||
{
|
||||
lua.getState()->new_usertype<Quests>("Quests",
|
||||
"getJournalChangesSize", &Quests::getJournalChangesSize,
|
||||
"getKillChangesSize", &Quests::getKillChangesSize,
|
||||
|
||||
"addJournalItem", &Quests::addJournalItem,
|
||||
"setJournalItem", &Quests::setJournalItem,
|
||||
"getJournalItem", &Quests::getJournalItem,
|
||||
|
||||
"addKill", &Quests::addKill,
|
||||
"getKillRefId", &Quests::getKillRefId,
|
||||
"getKillNumber", &Quests::getKillNumber
|
||||
);
|
||||
}
|
||||
|
||||
Quests::Quests(Player *player) : player(player), changedKills(false), changedJournal(false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Quests::~Quests()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Quests::update()
|
||||
{
|
||||
if (changedJournal)
|
||||
{
|
||||
changedJournal = false;
|
||||
auto packet = mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_JOURNAL);
|
||||
|
||||
packet->setPlayer(player);
|
||||
packet->Send(/*toOthers*/ false);
|
||||
}
|
||||
|
||||
if (changedKills)
|
||||
{
|
||||
changedKills = false;
|
||||
auto packet = mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_KILL_COUNT);
|
||||
|
||||
packet->setPlayer(player);
|
||||
packet->Send(/*toOthers*/ false);
|
||||
}
|
||||
}
|
||||
|
||||
size_t Quests::getJournalChangesSize() const
|
||||
{
|
||||
return player->journalChanges.journalItems.size();
|
||||
}
|
||||
|
||||
size_t Quests::getKillChangesSize() const
|
||||
{
|
||||
return player->killChanges.kills.size();
|
||||
}
|
||||
|
||||
void Quests::addJournalItem(JournalItem item)
|
||||
{
|
||||
player->journalChanges.journalItems.push_back(item.item);
|
||||
changedJournal = true;
|
||||
|
||||
}
|
||||
|
||||
void Quests::setJournalItem(unsigned int id, JournalItem item)
|
||||
{
|
||||
player->journalChanges.journalItems.at(id) = item.item;
|
||||
changedJournal = true;
|
||||
}
|
||||
|
||||
JournalItem Quests::getJournalItem(unsigned int id)
|
||||
{
|
||||
return JournalItem(player->journalChanges.journalItems.at(id));
|
||||
}
|
||||
|
||||
void Quests::addKill(const std::string &refId, int number)
|
||||
{
|
||||
player->killChanges.kills.push_back({refId, number});
|
||||
changedKills = true;
|
||||
}
|
||||
|
||||
std::string Quests::getKillRefId(unsigned int i) const
|
||||
{
|
||||
return player->killChanges.kills.at(i).refId;
|
||||
}
|
||||
|
||||
int Quests::getKillNumber(unsigned int i) const
|
||||
{
|
||||
return player->killChanges.kills.at(i).number;
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
//
|
||||
// Created by koncord on 25.08.17.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <components/openmw-mp/Base/BasePlayer.hpp>
|
||||
|
||||
class LuaState;
|
||||
class Player;
|
||||
|
||||
class JournalItem
|
||||
{
|
||||
public:
|
||||
static void Init(LuaState &lua);
|
||||
public:
|
||||
explicit JournalItem(mwmp::JournalItem item);
|
||||
~JournalItem();
|
||||
|
||||
std::string getQuest() const;
|
||||
void setQuest(const std::string &quest);
|
||||
|
||||
int getIndex() const;
|
||||
void setIndex(int index);
|
||||
|
||||
int getType() const;
|
||||
void setType(int type);
|
||||
|
||||
std::string getActorRefId() const;
|
||||
void setActorRefId(const std::string &refid);
|
||||
|
||||
|
||||
mwmp::JournalItem item;
|
||||
};
|
||||
|
||||
class Quests
|
||||
{
|
||||
public:
|
||||
static void Init(LuaState &lua);
|
||||
public:
|
||||
explicit Quests(Player *player);
|
||||
~Quests();
|
||||
|
||||
void update();
|
||||
|
||||
size_t getJournalChangesSize() const;
|
||||
size_t getKillChangesSize() const;
|
||||
|
||||
void addJournalItem(JournalItem item);
|
||||
void setJournalItem(unsigned int id, JournalItem item);
|
||||
JournalItem getJournalItem(unsigned int id);
|
||||
|
||||
void addKill(const std::string &refId, int number);
|
||||
std::string getKillRefId(unsigned int i) const;
|
||||
int getKillNumber(unsigned int i) const;
|
||||
|
||||
private:
|
||||
Player *player;
|
||||
bool changedKills, changedJournal;
|
||||
};
|
||||
|
||||
|
@ -1,93 +0,0 @@
|
||||
//
|
||||
// Created by koncord on 14.05.16.
|
||||
//
|
||||
|
||||
#include <Script/ScriptFunction.hpp>
|
||||
#include "PublicFnAPI.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
unordered_map<string, Public *> Public::publics;
|
||||
|
||||
Public::~Public()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Public::Public(ScriptFunc _public, const std::string &name, char ret_type, const std::string &def) : ScriptFunction(_public, ret_type, def)
|
||||
{
|
||||
publics.emplace(name, this);
|
||||
}
|
||||
|
||||
Public::Public(ScriptFuncLua _public, lua_State *lua, const std::string &name, char ret_type, const std::string &def) : ScriptFunction(
|
||||
_public, lua, ret_type, def)
|
||||
{
|
||||
publics.emplace(name, this);
|
||||
}
|
||||
|
||||
#if defined(ENABLE_PAWN)
|
||||
Public::Public(ScriptFuncPAWN _public, AMX* amx, const std::string& name, char ret_type, const std::string& def): ScriptFunction(_public, amx, ret_type, def)
|
||||
{
|
||||
publics.emplace(name, this);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
boost::any Public::Call(const std::string &name, const std::vector<boost::any> &args)
|
||||
{
|
||||
auto it = publics.find(name);
|
||||
if (it == publics.end())
|
||||
throw runtime_error("Public with name \"" + name + "\" does not exist");
|
||||
|
||||
return it->second->ScriptFunction::Call(args);
|
||||
}
|
||||
|
||||
|
||||
const std::string &Public::GetDefinition(const std::string &name)
|
||||
{
|
||||
auto it = publics.find(name);
|
||||
|
||||
if (it == publics.end())
|
||||
throw runtime_error("Public with name \"" + name + "\" does not exist");
|
||||
|
||||
return it->second->def;
|
||||
}
|
||||
|
||||
|
||||
bool Public::IsLua(const std::string &name)
|
||||
{
|
||||
#if !defined(ENABLE_LUA)
|
||||
return false;
|
||||
#else
|
||||
auto it = publics.find(name);
|
||||
if (it == publics.end())
|
||||
throw runtime_error("Public with name \"" + name + "\" does not exist");
|
||||
|
||||
return it->second->script_type == SCRIPT_LUA;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool Public::IsPAWN(const std::string &name)
|
||||
{
|
||||
#if !defined(ENABLE_PAWN)
|
||||
return false;
|
||||
#else
|
||||
auto it = publics.find(name);
|
||||
|
||||
if (it == publics.end())
|
||||
throw runtime_error("Public with name \"" + name + "\" does not exist");
|
||||
|
||||
return it->second->script_type == SCRIPT_PAWN;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void Public::DeleteAll()
|
||||
{
|
||||
for (auto it = publics.begin(); it != publics.end(); it++)
|
||||
{
|
||||
Public *_public = it->second;
|
||||
delete _public;
|
||||
publics.erase(it);
|
||||
}
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
//
|
||||
// Created by koncord on 14.05.16.
|
||||
//
|
||||
|
||||
#ifndef PLUGINSYSTEM3_PUBLICFNAPI_HPP
|
||||
#define PLUGINSYSTEM3_PUBLICFNAPI_HPP
|
||||
|
||||
#include <unordered_map>
|
||||
#include <Script/ScriptFunction.hpp>
|
||||
|
||||
|
||||
class Public : public ScriptFunction
|
||||
{
|
||||
private:
|
||||
~Public();
|
||||
|
||||
static std::unordered_map<std::string, Public *> publics;
|
||||
|
||||
Public(ScriptFunc _public, const std::string &name, char ret_type, const std::string &def);
|
||||
#if defined(ENABLE_PAWN)
|
||||
Public(ScriptFuncPAWN _public, AMX* amx, const std::string& name, char ret_type, const std::string& def);
|
||||
#endif
|
||||
#if defined(ENABLE_LUA)
|
||||
Public(ScriptFuncLua _public, lua_State *lua, const std::string &name, char ret_type, const std::string &def);
|
||||
#endif
|
||||
|
||||
public:
|
||||
template<typename... Args>
|
||||
static void MakePublic(Args &&... args)
|
||||
{ new Public(std::forward<Args>(args)...); }
|
||||
|
||||
static boost::any Call(const std::string &name, const std::vector<boost::any> &args);
|
||||
|
||||
static const std::string& GetDefinition(const std::string& name);
|
||||
|
||||
static bool IsPAWN(const std::string &name);
|
||||
static bool IsLua(const std::string &name);
|
||||
|
||||
static void DeleteAll();
|
||||
};
|
||||
|
||||
#endif //PLUGINSYSTEM3_PUBLICFNAPI_HPP
|
@ -1,238 +0,0 @@
|
||||
//
|
||||
// Created by koncord on 15.03.16.
|
||||
//
|
||||
|
||||
#include "TimerAPI.hpp"
|
||||
|
||||
#include <chrono>
|
||||
|
||||
#include <iostream>
|
||||
using namespace mwmp;
|
||||
using namespace std;
|
||||
|
||||
Timer::Timer(ScriptFunc callback, long msec, const std::string& def, std::vector<boost::any> args) : ScriptFunction(callback, 'v', def)
|
||||
{
|
||||
targetMsec = msec;
|
||||
this->args = args;
|
||||
end = true;
|
||||
}
|
||||
|
||||
#if defined(ENABLE_PAWN)
|
||||
Timer::Timer(AMX *amx, ScriptFuncPAWN callback, long msec, const std::string &def, std::vector<boost::any> args): ScriptFunction(callback, amx, 'v', def)
|
||||
{
|
||||
targetMsec = msec;
|
||||
this->args = args;
|
||||
end = true;
|
||||
}
|
||||
#endif
|
||||
#if defined(ENABLE_LUA)
|
||||
Timer::Timer(lua_State *lua, ScriptFuncLua callback, long msec, const std::string& def, std::vector<boost::any> args): ScriptFunction(callback, lua, 'v', def)
|
||||
{
|
||||
targetMsec = msec;
|
||||
this->args = args;
|
||||
end = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
void Timer::Tick()
|
||||
{
|
||||
if (end)
|
||||
return;
|
||||
|
||||
const auto duration = chrono::system_clock::now().time_since_epoch();
|
||||
const auto time = chrono::duration_cast<chrono::milliseconds>(duration).count();
|
||||
|
||||
if (time - startTime >= targetMsec)
|
||||
{
|
||||
end = true;
|
||||
Call(args);
|
||||
}
|
||||
}
|
||||
|
||||
bool Timer::IsEnd()
|
||||
{
|
||||
return end;
|
||||
}
|
||||
|
||||
void Timer::Stop()
|
||||
{
|
||||
end = true;
|
||||
}
|
||||
|
||||
void Timer::Restart(int msec)
|
||||
{
|
||||
targetMsec = msec;
|
||||
Start();
|
||||
}
|
||||
|
||||
void Timer::Start()
|
||||
{
|
||||
end = false;
|
||||
|
||||
const auto duration = chrono::system_clock::now().time_since_epoch();
|
||||
const auto msec = chrono::duration_cast<chrono::milliseconds>(duration).count();
|
||||
startTime = msec;
|
||||
}
|
||||
|
||||
int TimerAPI::pointer = 0;
|
||||
std::unordered_map<int, Timer* > TimerAPI::timers;
|
||||
|
||||
#if defined(ENABLE_PAWN)
|
||||
int TimerAPI::CreateTimerPAWN(AMX *amx, ScriptFuncPAWN callback, long msec, const string& def, std::vector<boost::any> args)
|
||||
{
|
||||
int id = -1;
|
||||
|
||||
for (auto timer : timers)
|
||||
{
|
||||
if (timer.second != nullptr)
|
||||
continue;
|
||||
timer.second = new Timer(amx, callback, msec, def, args);
|
||||
id = timer.first;
|
||||
}
|
||||
|
||||
if (id == -1)
|
||||
{
|
||||
timers[pointer] = new Timer(amx, callback, msec, def, args);
|
||||
id = pointer;
|
||||
pointer++;
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(ENABLE_LUA)
|
||||
int TimerAPI::CreateTimerLua(lua_State *lua, ScriptFuncLua callback, long msec, const std::string& def, std::vector<boost::any> args)
|
||||
{
|
||||
int id = -1;
|
||||
|
||||
for (auto timer : timers)
|
||||
{
|
||||
if (timer.second != nullptr)
|
||||
continue;
|
||||
timer.second = new Timer(lua, callback, msec, def, args);
|
||||
id = timer.first;
|
||||
}
|
||||
|
||||
if (id == -1)
|
||||
{
|
||||
timers[pointer] = new Timer(lua, callback, msec, def, args);
|
||||
id = pointer;
|
||||
pointer++;
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int TimerAPI::CreateTimer(ScriptFunc callback, long msec, const std::string &def, std::vector<boost::any> args)
|
||||
{
|
||||
int id = -1;
|
||||
|
||||
for (auto timer : timers)
|
||||
{
|
||||
if (timer.second != nullptr)
|
||||
continue;
|
||||
timer.second = new Timer(callback, msec, def, args);
|
||||
id = timer.first;
|
||||
}
|
||||
|
||||
if (id == -1)
|
||||
{
|
||||
timers[pointer] = new Timer(callback, msec, def, args);
|
||||
id = pointer;
|
||||
pointer++;
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
void TimerAPI::FreeTimer(int timerid)
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
if (timers.at(timerid) != nullptr)
|
||||
{
|
||||
delete timers[timerid];
|
||||
timers[timerid] = nullptr;
|
||||
}
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
std::cerr << "Timer " << timerid << " not found!" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
void TimerAPI::ResetTimer(int timerid, long msec)
|
||||
{
|
||||
try
|
||||
{
|
||||
timers.at(timerid)->Restart(msec);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
std::cerr << "Timer " << timerid << " not found!" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
void TimerAPI::StartTimer(int timerid)
|
||||
{
|
||||
try
|
||||
{
|
||||
Timer *timer = timers.at(timerid);
|
||||
if (timer == nullptr)
|
||||
throw 1;
|
||||
timer->Start();
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
std::cerr << "Timer " << timerid << " not found!" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
void TimerAPI::StopTimer(int timerid)
|
||||
{
|
||||
try
|
||||
{
|
||||
timers.at(timerid)->Stop();
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
std::cerr << "Timer " << timerid << " not found!" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
bool TimerAPI::IsEndTimer(int timerid)
|
||||
{
|
||||
bool ret = false;
|
||||
try
|
||||
{
|
||||
ret = timers.at(timerid)->IsEnd();
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
std::cerr << "Timer " << timerid << " not found!" << endl;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void TimerAPI::Terminate()
|
||||
{
|
||||
for (auto timer : timers)
|
||||
{
|
||||
if (timer.second != nullptr)
|
||||
delete timer.second;
|
||||
timer.second = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void TimerAPI::Tick()
|
||||
{
|
||||
for (auto timer : timers)
|
||||
{
|
||||
if (timer.second != nullptr)
|
||||
timer.second->Tick();
|
||||
}
|
||||
}
|
@ -1,70 +0,0 @@
|
||||
//
|
||||
// Created by koncord on 15.03.16.
|
||||
//
|
||||
|
||||
#ifndef OPENMW_TIMERAPI_HPP
|
||||
#define OPENMW_TIMERAPI_HPP
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <Script/Script.hpp>
|
||||
#include <Script/ScriptFunction.hpp>
|
||||
|
||||
namespace mwmp
|
||||
{
|
||||
|
||||
class TimerAPI;
|
||||
|
||||
class Timer: public ScriptFunction
|
||||
{
|
||||
friend class TimerAPI;
|
||||
|
||||
public:
|
||||
|
||||
Timer(ScriptFunc callback, long msec, const std::string& def, std::vector<boost::any> args);
|
||||
#if defined(ENABLE_PAWN)
|
||||
Timer(AMX *amx, ScriptFuncPAWN callback, long msec, const std::string& def, std::vector<boost::any> args);
|
||||
#endif
|
||||
#if defined(ENABLE_LUA)
|
||||
Timer(lua_State *lua, ScriptFuncLua callback, long msec, const std::string& def, std::vector<boost::any> args);
|
||||
#endif
|
||||
void Tick();
|
||||
|
||||
bool IsEnd();
|
||||
void Stop();
|
||||
void Start();
|
||||
void Restart(int msec);
|
||||
private:
|
||||
double startTime, targetMsec;
|
||||
std::string publ, arg_types;
|
||||
std::vector<boost::any> args;
|
||||
Script *scr;
|
||||
bool end;
|
||||
};
|
||||
|
||||
class TimerAPI
|
||||
{
|
||||
public:
|
||||
#if defined(ENABLE_PAWN)
|
||||
static int CreateTimerPAWN(AMX *amx, ScriptFuncPAWN callback, long msec, const std::string& def, std::vector<boost::any> args);
|
||||
#endif
|
||||
#if defined(ENABLE_LUA)
|
||||
static int CreateTimerLua(lua_State *lua, ScriptFuncLua callback, long msec, const std::string& def, std::vector<boost::any> args);
|
||||
#endif
|
||||
static int CreateTimer(ScriptFunc callback, long msec, const std::string& def, std::vector<boost::any> args);
|
||||
static void FreeTimer(int timerid);
|
||||
static void ResetTimer(int timerid, long msec);
|
||||
static void StartTimer(int timerid);
|
||||
static void StopTimer(int timerid);
|
||||
static bool IsEndTimer(int timerid);
|
||||
|
||||
static void Terminate();
|
||||
|
||||
static void Tick();
|
||||
private:
|
||||
static std::unordered_map<int, Timer* > timers;
|
||||
static int pointer;
|
||||
};
|
||||
}
|
||||
|
||||
#endif //OPENMW_TIMERAPI_HPP
|
@ -0,0 +1,100 @@
|
||||
//
|
||||
// Created by koncord on 08.08.17.
|
||||
//
|
||||
#include "CommandController.hpp"
|
||||
|
||||
#include <boost/spirit/home/x3.hpp>
|
||||
#include <iostream>
|
||||
#include "Player.hpp"
|
||||
#include "LuaState.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
void CommandController::Init(LuaState &lua)
|
||||
{
|
||||
sol::table cmdCtrlTable = lua.getState()->create_named_table("CommandController");
|
||||
|
||||
cmdCtrlTable["registerCommand"] = [&lua](const std::string &command, sol::function func, const std::string &helpMessage) {
|
||||
return lua.getCmdCtrl().registerCommand(command, func, helpMessage);
|
||||
};
|
||||
|
||||
cmdCtrlTable["unregisterCommand"] = [&lua](const std::string &command) {
|
||||
lua.getCmdCtrl().unregisterCommand(command);
|
||||
};
|
||||
|
||||
cmdCtrlTable["hasCommand"] = [&lua](const std::string &command) {
|
||||
return lua.getCmdCtrl().hasCommand(command);
|
||||
};
|
||||
|
||||
cmdCtrlTable["getHelpStrings"] = [&lua]() {
|
||||
auto &commands = lua.getCmdCtrl().commands;
|
||||
sol::table helpTable = lua.getState()->create_table(commands.size(), 0);
|
||||
|
||||
for (const auto &cmd : commands)
|
||||
helpTable.add(cmd.first, cmd.second.helpMessage);
|
||||
|
||||
return helpTable;
|
||||
};
|
||||
}
|
||||
|
||||
bool CommandController::registerCommand(const std::string &command, sol::function func, const std::string &helpMessage)
|
||||
{
|
||||
auto iter = commands.find(command);
|
||||
if (iter == commands.end())
|
||||
{
|
||||
commands.emplace(command, Command {std::move(func), helpMessage});
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void CommandController::unregisterCommand(const std::string &command)
|
||||
{
|
||||
commands.erase(command);
|
||||
}
|
||||
|
||||
bool CommandController::hasCommand(const std::string &command)
|
||||
{
|
||||
return commands.find(command) != commands.end();
|
||||
}
|
||||
|
||||
std::pair<CommandController::ExecResult, std::string> CommandController::exec(std::shared_ptr<Player> player, const std::string &message)
|
||||
{
|
||||
char cmdChar = message[0];
|
||||
if (message.size() < 2 || (cmdChar != '/' && cmdChar != '!'))
|
||||
return make_pair(ExecResult::NOT_CMD, "");
|
||||
|
||||
auto tokens = cmdParser(message);
|
||||
|
||||
auto cmd = commands.find(&tokens[0][1]);
|
||||
if (cmd != commands.end())
|
||||
{
|
||||
tokens.pop_front();
|
||||
bool result = cmd->second.func(player, sol::as_table(tokens));
|
||||
if (result)
|
||||
return make_pair(ExecResult::SUCCESS, "");
|
||||
|
||||
return make_pair(ExecResult::FAIL, cmd->second.helpMessage);
|
||||
}
|
||||
|
||||
return make_pair(ExecResult::NOT_FOUND, "");
|
||||
}
|
||||
|
||||
std::deque<std::string> CommandController::cmdParser(const std::string &message)
|
||||
{
|
||||
deque<string> ret;
|
||||
namespace x3 = boost::spirit::x3;
|
||||
auto const sep = ' ';
|
||||
auto const quoted = '"' >> *~x3::char_('"') >> '"';
|
||||
auto const unquoted = *~x3::char_(sep);
|
||||
auto const arguments = (quoted | unquoted) % sep;
|
||||
/*auto const command = '/' >> *~x3::char_(sep) >> sep;
|
||||
|
||||
if (!x3::phrase_parse(message.cbegin(), message.cend(), arguments, command, ret))
|
||||
throw runtime_error("failed to parse message: "+ message);*/
|
||||
|
||||
if (!x3::parse(message.cbegin(), message.cend(), arguments, ret))
|
||||
throw runtime_error("failed to parse message: " + message);
|
||||
|
||||
return ret;
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
//
|
||||
// Created by koncord on 08.08.17.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "sol.hpp"
|
||||
#include "Utils.hpp"
|
||||
#include <string>
|
||||
#include <deque>
|
||||
|
||||
class Player;
|
||||
class LuaState;
|
||||
|
||||
struct Command
|
||||
{
|
||||
sol::function func;
|
||||
std::string helpMessage;
|
||||
};
|
||||
|
||||
class CommandController
|
||||
{
|
||||
typedef std::unordered_map<std::string, Command> Container;
|
||||
typedef Container::iterator Iter;
|
||||
typedef Container::const_iterator CIter;
|
||||
public:
|
||||
static void Init(LuaState &lua);
|
||||
public:
|
||||
|
||||
enum class ExecResult : int
|
||||
{
|
||||
NOT_FOUND,
|
||||
SUCCESS,
|
||||
FAIL,
|
||||
NOT_CMD
|
||||
};
|
||||
|
||||
/**
|
||||
* Register new command. Only unique commands are allowed.
|
||||
* @param command name of command. Case sensitive. No need in command prefix ('/' or '!').
|
||||
* @param helpMessage help message. Shows in the '/help' command also appears if exec() fails.
|
||||
* @param callback Will be called when command is called.
|
||||
* @return false if the command already registered.
|
||||
*/
|
||||
bool registerCommand(const std::string &command, sol::function callback, const std::string &helpMessage);
|
||||
/**
|
||||
* Removes a registered command
|
||||
* @param command name of command.
|
||||
*/
|
||||
void unregisterCommand(const std::string &command);
|
||||
|
||||
/**
|
||||
* Check a command is exist.
|
||||
* @param command name of command
|
||||
* @return false if the command did not exist.
|
||||
*/
|
||||
bool hasCommand(const std::string &command);
|
||||
|
||||
std::pair<ExecResult, std::string> exec(std::shared_ptr<Player> player, const std::string &message);
|
||||
private:
|
||||
std::deque<std::string> cmdParser(const std::string &message);
|
||||
Container commands;
|
||||
};
|
@ -0,0 +1,153 @@
|
||||
//
|
||||
// Created by koncord on 30.07.17.
|
||||
//
|
||||
|
||||
#include <iostream>
|
||||
#include "EventController.hpp"
|
||||
|
||||
using namespace std;
|
||||
#define ADD_CORE_EVENT(event) #event, CoreEvent::event
|
||||
void EventController::Init(LuaState &lua)
|
||||
{
|
||||
sol::table eventsTable = lua.getState()->create_named_table("Event");
|
||||
|
||||
eventsTable["register"] = [&lua](int event, sol::function func, sol::this_environment te) {
|
||||
sol::environment& env = te;
|
||||
string modname = env["ModInfo"]["name"];
|
||||
lua.getEventCtrl().registerEvent(event, env, func);
|
||||
};
|
||||
eventsTable["stop"] = [&lua](int event) {
|
||||
lua.getEventCtrl().stop(event);
|
||||
};
|
||||
eventsTable["create"] = [&lua]() {
|
||||
return lua.getEventCtrl().createEvent();
|
||||
};
|
||||
eventsTable["raise"] = [&lua](unsigned event, sol::table data) {
|
||||
lua.getEventCtrl().raiseEvent(event, data);
|
||||
};
|
||||
eventsTable["raiseSpecified"] = [&lua](unsigned event, const std::string &modname, sol::table data) {
|
||||
lua.getEventCtrl().raiseEvent(event, data, modname);
|
||||
};
|
||||
}
|
||||
|
||||
EventController::EventController(LuaState *luaCtrl)
|
||||
{
|
||||
this->luaCtrl = luaCtrl;
|
||||
|
||||
#ifdef SERVER_DEBUG
|
||||
luaCtrl->getState()->new_enum<false>
|
||||
#else
|
||||
luaCtrl->getState()->new_enum
|
||||
#endif
|
||||
("Events",
|
||||
ADD_CORE_EVENT(ON_POST_INIT),
|
||||
ADD_CORE_EVENT(ON_EXIT),
|
||||
ADD_CORE_EVENT(ON_PLAYER_CONNECT),
|
||||
ADD_CORE_EVENT(ON_PLAYER_DISCONNECT),
|
||||
ADD_CORE_EVENT(ON_PLAYER_DEATH),
|
||||
ADD_CORE_EVENT(ON_PLAYER_RESURRECT),
|
||||
ADD_CORE_EVENT(ON_PLAYER_CELLCHANGE),
|
||||
ADD_CORE_EVENT(ON_PLAYER_KILLCOUNT),
|
||||
ADD_CORE_EVENT(ON_PLAYER_ATTRIBUTE),
|
||||
ADD_CORE_EVENT(ON_PLAYER_SKILL),
|
||||
ADD_CORE_EVENT(ON_PLAYER_LEVEL),
|
||||
ADD_CORE_EVENT(ON_PLAYER_BOUNTY),
|
||||
ADD_CORE_EVENT(ON_PLAYER_EQUIPMENT),
|
||||
ADD_CORE_EVENT(ON_PLAYER_INVENTORY),
|
||||
ADD_CORE_EVENT(ON_PLAYER_JOURNAL),
|
||||
ADD_CORE_EVENT(ON_PLAYER_FACTION),
|
||||
ADD_CORE_EVENT(ON_PLAYER_SHAPESHIFT),
|
||||
ADD_CORE_EVENT(ON_PLAYER_SPELLBOOK),
|
||||
ADD_CORE_EVENT(ON_PLAYER_TOPIC),
|
||||
ADD_CORE_EVENT(ON_PLAYER_DISPOSITION),
|
||||
ADD_CORE_EVENT(ON_PLAYER_BOOK),
|
||||
ADD_CORE_EVENT(ON_PLAYER_MAP),
|
||||
ADD_CORE_EVENT(ON_PLAYER_REST),
|
||||
ADD_CORE_EVENT(ON_PLAYER_SENDMESSAGE),
|
||||
ADD_CORE_EVENT(ON_PLAYER_ENDCHARGEN),
|
||||
ADD_CORE_EVENT(ON_GUI_ACTION),
|
||||
ADD_CORE_EVENT(ON_REQUEST_PLUGIN_LIST),
|
||||
ADD_CORE_EVENT(ON_MP_REFNUM),
|
||||
ADD_CORE_EVENT(ON_ACTOR_EQUIPMENT),
|
||||
ADD_CORE_EVENT(ON_ACTOR_CELL_CHANGE),
|
||||
ADD_CORE_EVENT(ON_ACTOR_LIST),
|
||||
ADD_CORE_EVENT(ON_ACTOR_TEST),
|
||||
ADD_CORE_EVENT(ON_CELL_LOAD),
|
||||
ADD_CORE_EVENT(ON_CELL_UNLOAD),
|
||||
ADD_CORE_EVENT(ON_CELL_DELETION),
|
||||
ADD_CORE_EVENT(ON_CONTAINER),
|
||||
ADD_CORE_EVENT(ON_DOOR_STATE),
|
||||
ADD_CORE_EVENT(ON_OBJECT_PLACE),
|
||||
ADD_CORE_EVENT(ON_OBJECT_STATE),
|
||||
ADD_CORE_EVENT(ON_OBJECT_SPAWN),
|
||||
ADD_CORE_EVENT(ON_OBJECT_DELETE),
|
||||
ADD_CORE_EVENT(ON_OBJECT_LOCK),
|
||||
ADD_CORE_EVENT(ON_OBJECT_SCALE),
|
||||
ADD_CORE_EVENT(ON_OBJECT_TRAP)
|
||||
);
|
||||
|
||||
sol::state &state = *luaCtrl->getState();
|
||||
sol::table eventsEnum = state["Events"];
|
||||
for (int i = CoreEvent::FIRST; i < CoreEvent::LAST; ++i)
|
||||
{
|
||||
#ifdef SERVER_DEBUG
|
||||
bool found = false;
|
||||
eventsEnum.for_each([&found, &i](sol::object key, sol::object value){
|
||||
if (value.as<int>() == i)
|
||||
{
|
||||
found = true;
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
if (!found)
|
||||
throw runtime_error("Event " + to_string(i) + " is not registered. Dear developer, please fix me :D");
|
||||
#endif
|
||||
events[i]; // create core event
|
||||
}
|
||||
}
|
||||
|
||||
void EventController::registerEvent(int event, sol::environment &env, sol::function& func)
|
||||
{
|
||||
auto iter = events.find(event);
|
||||
if (iter != events.end())
|
||||
iter->second.push(env, func);
|
||||
}
|
||||
|
||||
void EventController::stop(int event)
|
||||
{
|
||||
printf("EventController::stop\n");
|
||||
auto iter = events.find(event);
|
||||
if (iter != events.end())
|
||||
iter->second.stop();
|
||||
}
|
||||
|
||||
CallbackCollection &EventController::GetEvents(Event event)
|
||||
{
|
||||
return events.at(event);
|
||||
}
|
||||
|
||||
Event EventController::createEvent()
|
||||
{
|
||||
events[lastEvent];
|
||||
return lastEvent++;
|
||||
}
|
||||
|
||||
void EventController::raiseEvent(Event id, sol::table data, const string &modname)
|
||||
{
|
||||
auto iter = events.find(id);
|
||||
if (iter != events.end())
|
||||
{
|
||||
if (!modname.empty())
|
||||
{
|
||||
auto f = std::find_if (iter->second.begin(), iter->second.end(), [&modname](const auto &item){
|
||||
return item.first["ModName"]["name"] == modname;
|
||||
});
|
||||
if (f != iter->second.end())
|
||||
f->second.call(data); // call only specified mod
|
||||
}
|
||||
iter->second.call(CallbackCollection::type_tag<void>(), data); // call all registered events with this id
|
||||
}
|
||||
else
|
||||
cerr << "Event with id: " << id << " is not registered" << endl;
|
||||
}
|
@ -0,0 +1,166 @@
|
||||
//
|
||||
// Created by koncord on 30.07.17.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "sol.hpp"
|
||||
#include "Utils.hpp"
|
||||
#include "LuaState.hpp"
|
||||
|
||||
typedef unsigned Event;
|
||||
|
||||
namespace CoreEvent
|
||||
{
|
||||
enum
|
||||
{
|
||||
ON_EXIT = 0,
|
||||
ON_POST_INIT,
|
||||
ON_REQUEST_PLUGIN_LIST,
|
||||
ON_PLAYER_CONNECT,
|
||||
ON_PLAYER_DISCONNECT,
|
||||
ON_PLAYER_DEATH,
|
||||
ON_PLAYER_RESURRECT,
|
||||
ON_PLAYER_CELLCHANGE,
|
||||
ON_PLAYER_KILLCOUNT,
|
||||
ON_PLAYER_ATTRIBUTE,
|
||||
ON_PLAYER_SKILL,
|
||||
ON_PLAYER_LEVEL,
|
||||
ON_PLAYER_BOUNTY,
|
||||
ON_PLAYER_EQUIPMENT,
|
||||
ON_PLAYER_INVENTORY,
|
||||
ON_PLAYER_JOURNAL,
|
||||
ON_PLAYER_FACTION,
|
||||
ON_PLAYER_SHAPESHIFT,
|
||||
ON_PLAYER_SPELLBOOK,
|
||||
ON_PLAYER_TOPIC,
|
||||
ON_PLAYER_DISPOSITION,
|
||||
ON_PLAYER_BOOK,
|
||||
ON_PLAYER_MAP,
|
||||
ON_PLAYER_REST,
|
||||
ON_PLAYER_SENDMESSAGE,
|
||||
ON_PLAYER_ENDCHARGEN,
|
||||
|
||||
ON_GUI_ACTION,
|
||||
ON_MP_REFNUM,
|
||||
|
||||
ON_ACTOR_EQUIPMENT,
|
||||
ON_ACTOR_CELL_CHANGE,
|
||||
ON_ACTOR_LIST,
|
||||
ON_ACTOR_TEST,
|
||||
|
||||
ON_CELL_LOAD,
|
||||
ON_CELL_UNLOAD,
|
||||
ON_CELL_DELETION,
|
||||
|
||||
ON_CONTAINER,
|
||||
ON_DOOR_STATE,
|
||||
ON_OBJECT_PLACE,
|
||||
ON_OBJECT_STATE,
|
||||
ON_OBJECT_SPAWN,
|
||||
ON_OBJECT_DELETE,
|
||||
ON_OBJECT_LOCK,
|
||||
ON_OBJECT_SCALE,
|
||||
ON_OBJECT_TRAP,
|
||||
|
||||
LAST,
|
||||
};
|
||||
const int FIRST = ON_EXIT;
|
||||
}
|
||||
|
||||
class CallbackCollection // todo: add sort by dependencies
|
||||
{
|
||||
public:
|
||||
typedef std::vector<std::pair<sol::environment, sol::function>> Container;
|
||||
typedef Container::iterator Iterator;
|
||||
typedef Container::const_iterator CIterator;
|
||||
|
||||
template<typename> struct type_tag {};
|
||||
|
||||
void push(sol::environment &env, sol::function &func) { functions.emplace_back(env, func); }
|
||||
CIterator begin() const { return functions.begin(); }
|
||||
CIterator end() const { return functions.end(); }
|
||||
|
||||
void stop() {_stop = true;}
|
||||
bool isStoped() const {return _stop;}
|
||||
CIterator stopedAt() const { return lastCalled; }
|
||||
|
||||
auto get(const std::string &modname)
|
||||
{
|
||||
for(auto iter = functions.cbegin(); iter != functions.cend(); ++iter)
|
||||
{
|
||||
if(iter->first["ModName"]["name"] == modname)
|
||||
return iter;
|
||||
}
|
||||
return functions.cend();
|
||||
}
|
||||
|
||||
|
||||
template<typename... Args>
|
||||
void call(type_tag<void>, Args&&... args)
|
||||
{
|
||||
lastCalled = functions.end();
|
||||
_stop = false;
|
||||
for(CIterator iter = functions.begin(); iter != functions.end(); ++iter)
|
||||
{
|
||||
if(!_stop)
|
||||
iter->second.call(std::forward<Args>(args)...);
|
||||
else
|
||||
{
|
||||
lastCalled = iter;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template<typename R, typename... Args>
|
||||
decltype(auto) call(type_tag<R>, Args&&... args)
|
||||
{
|
||||
R ret;
|
||||
|
||||
lastCalled = functions.end();
|
||||
_stop = false;
|
||||
for(CIterator iter = functions.begin(); iter != functions.end(); ++iter)
|
||||
{
|
||||
if (!_stop)
|
||||
ret = iter->second.call(std::forward<Args>(args)...);
|
||||
else
|
||||
{
|
||||
lastCalled = iter;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private:
|
||||
Container functions;
|
||||
CIterator lastCalled;
|
||||
bool _stop = false;
|
||||
};
|
||||
|
||||
class EventController
|
||||
{
|
||||
public:
|
||||
static void Init(LuaState &lua);
|
||||
public:
|
||||
explicit EventController(LuaState *luaCtrl);
|
||||
typedef std::unordered_map<int, CallbackCollection> Container;
|
||||
|
||||
void registerEvent(int event, sol::environment &env, sol::function& func);
|
||||
CallbackCollection& GetEvents(Event event);
|
||||
Event createEvent();
|
||||
void raiseEvent(Event id, sol::table data, const std::string &modname = "");
|
||||
void stop(int event);
|
||||
|
||||
template<Event event, typename R = void, typename... Args>
|
||||
R Call(Args&&... args)
|
||||
{
|
||||
return events.at(event).call(CallbackCollection::type_tag<R>{}, std::forward<Args>(args)...);
|
||||
}
|
||||
private:
|
||||
Container events;
|
||||
Event lastEvent = CoreEvent::LAST;
|
||||
LuaState *luaCtrl;
|
||||
};
|
@ -1,330 +0,0 @@
|
||||
#include <components/openmw-mp/NetworkMessages.hpp>
|
||||
#include <components/openmw-mp/Base/BaseActor.hpp>
|
||||
|
||||
#include <apps/openmw-mp/Networking.hpp>
|
||||
#include <apps/openmw-mp/Player.hpp>
|
||||
#include <apps/openmw-mp/Utils.hpp>
|
||||
#include <apps/openmw-mp/Script/ScriptFunctions.hpp>
|
||||
|
||||
#include <components/esm/creaturestats.hpp>
|
||||
|
||||
#include "Actors.hpp"
|
||||
|
||||
using namespace mwmp;
|
||||
|
||||
BaseActorList *readActorList;
|
||||
BaseActorList writeActorList;
|
||||
|
||||
BaseActor tempActor;
|
||||
const BaseActor emptyActor = {};
|
||||
|
||||
static std::string tempCellDescription;
|
||||
|
||||
void ActorFunctions::ReadLastActorList() noexcept
|
||||
{
|
||||
readActorList = mwmp::Networking::getPtr()->getLastActorList();
|
||||
}
|
||||
|
||||
void ActorFunctions::ReadCellActorList(const char* cellDescription) noexcept
|
||||
{
|
||||
ESM::Cell esmCell = Utils::getCellFromDescription(cellDescription);
|
||||
Cell *serverCell = CellController::get()->getCell(&esmCell);
|
||||
readActorList = serverCell->getActorList();
|
||||
}
|
||||
|
||||
void ActorFunctions::InitializeActorList(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
writeActorList.cell.blank();
|
||||
writeActorList.baseActors.clear();
|
||||
writeActorList.guid = player->guid;
|
||||
}
|
||||
|
||||
unsigned int ActorFunctions::GetActorListSize() noexcept
|
||||
{
|
||||
return readActorList->count;
|
||||
}
|
||||
|
||||
unsigned char ActorFunctions::GetActorListAction() noexcept
|
||||
{
|
||||
return readActorList->action;
|
||||
}
|
||||
|
||||
const char *ActorFunctions::GetActorCell(unsigned int i) noexcept
|
||||
{
|
||||
tempCellDescription = readActorList->baseActors.at(i).cell.getDescription();
|
||||
return tempCellDescription.c_str();
|
||||
}
|
||||
|
||||
const char *ActorFunctions::GetActorRefId(unsigned int i) noexcept
|
||||
{
|
||||
return readActorList->baseActors.at(i).refId.c_str();
|
||||
}
|
||||
|
||||
int ActorFunctions::GetActorRefNumIndex(unsigned int i) noexcept
|
||||
{
|
||||
return readActorList->baseActors.at(i).refNumIndex;
|
||||
}
|
||||
|
||||
int ActorFunctions::GetActorMpNum(unsigned int i) noexcept
|
||||
{
|
||||
return readActorList->baseActors.at(i).mpNum;
|
||||
}
|
||||
|
||||
double ActorFunctions::GetActorPosX(unsigned int i) noexcept
|
||||
{
|
||||
return readActorList->baseActors.at(i).position.pos[0];
|
||||
}
|
||||
|
||||
double ActorFunctions::GetActorPosY(unsigned int i) noexcept
|
||||
{
|
||||
return readActorList->baseActors.at(i).position.pos[1];
|
||||
}
|
||||
|
||||
double ActorFunctions::GetActorPosZ(unsigned int i) noexcept
|
||||
{
|
||||
return readActorList->baseActors.at(i).position.pos[2];
|
||||
}
|
||||
|
||||
double ActorFunctions::GetActorRotX(unsigned int i) noexcept
|
||||
{
|
||||
return readActorList->baseActors.at(i).position.rot[0];
|
||||
}
|
||||
|
||||
double ActorFunctions::GetActorRotY(unsigned int i) noexcept
|
||||
{
|
||||
return readActorList->baseActors.at(i).position.rot[1];
|
||||
}
|
||||
|
||||
double ActorFunctions::GetActorRotZ(unsigned int i) noexcept
|
||||
{
|
||||
return readActorList->baseActors.at(i).position.rot[2];
|
||||
}
|
||||
|
||||
double ActorFunctions::GetActorHealthBase(unsigned int i) noexcept
|
||||
{
|
||||
return readActorList->baseActors.at(i).creatureStats.mDynamic[0].mBase;
|
||||
}
|
||||
|
||||
double ActorFunctions::GetActorHealthCurrent(unsigned int i) noexcept
|
||||
{
|
||||
return readActorList->baseActors.at(i).creatureStats.mDynamic[0].mCurrent;
|
||||
}
|
||||
|
||||
double ActorFunctions::GetActorHealthModified(unsigned int i) noexcept
|
||||
{
|
||||
return readActorList->baseActors.at(i).creatureStats.mDynamic[0].mMod;
|
||||
}
|
||||
|
||||
double ActorFunctions::GetActorMagickaBase(unsigned int i) noexcept
|
||||
{
|
||||
return readActorList->baseActors.at(i).creatureStats.mDynamic[1].mBase;
|
||||
}
|
||||
|
||||
double ActorFunctions::GetActorMagickaCurrent(unsigned int i) noexcept
|
||||
{
|
||||
return readActorList->baseActors.at(i).creatureStats.mDynamic[1].mCurrent;
|
||||
}
|
||||
|
||||
double ActorFunctions::GetActorMagickaModified(unsigned int i) noexcept
|
||||
{
|
||||
return readActorList->baseActors.at(i).creatureStats.mDynamic[1].mMod;
|
||||
}
|
||||
|
||||
double ActorFunctions::GetActorFatigueBase(unsigned int i) noexcept
|
||||
{
|
||||
return readActorList->baseActors.at(i).creatureStats.mDynamic[2].mBase;
|
||||
}
|
||||
|
||||
double ActorFunctions::GetActorFatigueCurrent(unsigned int i) noexcept
|
||||
{
|
||||
return readActorList->baseActors.at(i).creatureStats.mDynamic[2].mCurrent;
|
||||
}
|
||||
|
||||
double ActorFunctions::GetActorFatigueModified(unsigned int i) noexcept
|
||||
{
|
||||
return readActorList->baseActors.at(i).creatureStats.mDynamic[2].mMod;
|
||||
}
|
||||
|
||||
const char *ActorFunctions::GetActorEquipmentItemRefId(unsigned int i, unsigned short slot) noexcept
|
||||
{
|
||||
return readActorList->baseActors.at(i).equipedItems[slot].refId.c_str();
|
||||
}
|
||||
|
||||
int ActorFunctions::GetActorEquipmentItemCount(unsigned int i, unsigned short slot) noexcept
|
||||
{
|
||||
return readActorList->baseActors.at(i).equipedItems[slot].count;
|
||||
}
|
||||
|
||||
int ActorFunctions::GetActorEquipmentItemCharge(unsigned int i, unsigned short slot) noexcept
|
||||
{
|
||||
return readActorList->baseActors.at(i).equipedItems[slot].charge;
|
||||
}
|
||||
|
||||
bool ActorFunctions::DoesActorHavePosition(unsigned int i) noexcept
|
||||
{
|
||||
return readActorList->baseActors.at(i).hasPositionData;
|
||||
}
|
||||
|
||||
bool ActorFunctions::DoesActorHaveStatsDynamic(unsigned int i) noexcept
|
||||
{
|
||||
return readActorList->baseActors.at(i).hasStatsDynamicData;
|
||||
}
|
||||
|
||||
void ActorFunctions::SetActorListCell(const char* cellDescription) noexcept
|
||||
{
|
||||
writeActorList.cell = Utils::getCellFromDescription(cellDescription);
|
||||
}
|
||||
|
||||
void ActorFunctions::SetActorListAction(unsigned char action) noexcept
|
||||
{
|
||||
writeActorList.action = action;
|
||||
}
|
||||
|
||||
void ActorFunctions::SetActorCell(const char* cellDescription) noexcept
|
||||
{
|
||||
tempActor.cell = Utils::getCellFromDescription(cellDescription);
|
||||
}
|
||||
|
||||
void ActorFunctions::SetActorRefId(const char* refId) noexcept
|
||||
{
|
||||
tempActor.refId = refId;
|
||||
}
|
||||
|
||||
void ActorFunctions::SetActorRefNumIndex(int refNumIndex) noexcept
|
||||
{
|
||||
tempActor.refNumIndex = refNumIndex;
|
||||
}
|
||||
|
||||
void ActorFunctions::SetActorMpNum(int mpNum) noexcept
|
||||
{
|
||||
tempActor.mpNum = mpNum;
|
||||
}
|
||||
|
||||
void ActorFunctions::SetActorPosition(double x, double y, double z) noexcept
|
||||
{
|
||||
tempActor.position.pos[0] = x;
|
||||
tempActor.position.pos[1] = y;
|
||||
tempActor.position.pos[2] = z;
|
||||
}
|
||||
|
||||
void ActorFunctions::SetActorRotation(double x, double y, double z) noexcept
|
||||
{
|
||||
tempActor.position.rot[0] = x;
|
||||
tempActor.position.rot[1] = y;
|
||||
tempActor.position.rot[2] = z;
|
||||
}
|
||||
|
||||
void ActorFunctions::SetActorHealthBase(double value) noexcept
|
||||
{
|
||||
tempActor.creatureStats.mDynamic[0].mBase = value;
|
||||
}
|
||||
|
||||
void ActorFunctions::SetActorHealthCurrent(double value) noexcept
|
||||
{
|
||||
tempActor.creatureStats.mDynamic[0].mCurrent = value;
|
||||
}
|
||||
|
||||
void ActorFunctions::SetActorHealthModified(double value) noexcept
|
||||
{
|
||||
tempActor.creatureStats.mDynamic[0].mMod = value;
|
||||
}
|
||||
|
||||
void ActorFunctions::SetActorMagickaBase(double value) noexcept
|
||||
{
|
||||
tempActor.creatureStats.mDynamic[1].mBase = value;
|
||||
}
|
||||
|
||||
void ActorFunctions::SetActorMagickaCurrent(double value) noexcept
|
||||
{
|
||||
tempActor.creatureStats.mDynamic[1].mCurrent = value;
|
||||
}
|
||||
|
||||
void ActorFunctions::SetActorMagickaModified(double value) noexcept
|
||||
{
|
||||
tempActor.creatureStats.mDynamic[1].mMod = value;
|
||||
}
|
||||
|
||||
void ActorFunctions::SetActorFatigueBase(double value) noexcept
|
||||
{
|
||||
tempActor.creatureStats.mDynamic[2].mBase = value;
|
||||
}
|
||||
|
||||
void ActorFunctions::SetActorFatigueCurrent(double value) noexcept
|
||||
{
|
||||
tempActor.creatureStats.mDynamic[2].mCurrent = value;
|
||||
}
|
||||
|
||||
void ActorFunctions::SetActorFatigueModified(double value) noexcept
|
||||
{
|
||||
tempActor.creatureStats.mDynamic[2].mMod = value;
|
||||
}
|
||||
|
||||
void ActorFunctions::EquipActorItem(unsigned short slot, const char *refId, unsigned int count, int charge) noexcept
|
||||
{
|
||||
tempActor.equipedItems[slot].refId = refId;
|
||||
tempActor.equipedItems[slot].count = count;
|
||||
tempActor.equipedItems[slot].charge = charge;
|
||||
}
|
||||
|
||||
void ActorFunctions::UnequipActorItem(unsigned short slot) noexcept
|
||||
{
|
||||
ActorFunctions::EquipActorItem(slot, "", 0, -1);
|
||||
}
|
||||
|
||||
void ActorFunctions::AddActor() noexcept
|
||||
{
|
||||
writeActorList.baseActors.push_back(tempActor);
|
||||
|
||||
tempActor = emptyActor;
|
||||
}
|
||||
|
||||
void ActorFunctions::SendActorList() noexcept
|
||||
{
|
||||
mwmp::Networking::get().getActorPacketController()->GetPacket(ID_ACTOR_LIST)->setActorList(&writeActorList);
|
||||
mwmp::Networking::get().getActorPacketController()->GetPacket(ID_ACTOR_LIST)->Send(writeActorList.guid);
|
||||
}
|
||||
|
||||
void ActorFunctions::SendActorAuthority() noexcept
|
||||
{
|
||||
Cell *serverCell = CellController::get()->getCell(&writeActorList.cell);
|
||||
|
||||
if (serverCell != nullptr)
|
||||
{
|
||||
serverCell->setAuthority(writeActorList.guid);
|
||||
|
||||
mwmp::ActorPacket *authorityPacket = mwmp::Networking::get().getActorPacketController()->GetPacket(ID_ACTOR_AUTHORITY);
|
||||
authorityPacket->setActorList(&writeActorList);
|
||||
authorityPacket->Send(writeActorList.guid);
|
||||
|
||||
// Also send this to everyone else who has the cell loaded
|
||||
serverCell->sendToLoaded(authorityPacket, &writeActorList);
|
||||
}
|
||||
}
|
||||
|
||||
void ActorFunctions::SendActorPosition() noexcept
|
||||
{
|
||||
mwmp::Networking::get().getActorPacketController()->GetPacket(ID_ACTOR_POSITION)->setActorList(&writeActorList);
|
||||
mwmp::Networking::get().getActorPacketController()->GetPacket(ID_ACTOR_POSITION)->Send(writeActorList.guid);
|
||||
}
|
||||
|
||||
void ActorFunctions::SendActorStatsDynamic() noexcept
|
||||
{
|
||||
mwmp::Networking::get().getActorPacketController()->GetPacket(ID_ACTOR_STATS_DYNAMIC)->setActorList(&writeActorList);
|
||||
mwmp::Networking::get().getActorPacketController()->GetPacket(ID_ACTOR_STATS_DYNAMIC)->Send(writeActorList.guid);
|
||||
}
|
||||
|
||||
void ActorFunctions::SendActorEquipment() noexcept
|
||||
{
|
||||
mwmp::Networking::get().getActorPacketController()->GetPacket(ID_ACTOR_EQUIPMENT)->setActorList(&writeActorList);
|
||||
mwmp::Networking::get().getActorPacketController()->GetPacket(ID_ACTOR_EQUIPMENT)->Send(writeActorList.guid);
|
||||
}
|
||||
|
||||
void ActorFunctions::SendActorCellChange() noexcept
|
||||
{
|
||||
mwmp::Networking::get().getActorPacketController()->GetPacket(ID_ACTOR_CELL_CHANGE)->setActorList(&writeActorList);
|
||||
mwmp::Networking::get().getActorPacketController()->GetPacket(ID_ACTOR_CELL_CHANGE)->Send(writeActorList.guid);
|
||||
}
|
||||
|
@ -1,563 +0,0 @@
|
||||
#ifndef OPENMW_ACTORAPI_HPP
|
||||
#define OPENMW_ACTORAPI_HPP
|
||||
|
||||
#define ACTORAPI \
|
||||
{"ReadLastActorList", ActorFunctions::ReadLastActorList},\
|
||||
{"ReadCellActorList", ActorFunctions::ReadCellActorList},\
|
||||
{"InitializeActorList", ActorFunctions::InitializeActorList},\
|
||||
\
|
||||
{"GetActorListSize", ActorFunctions::GetActorListSize},\
|
||||
{"GetActorListAction", ActorFunctions::GetActorListAction},\
|
||||
\
|
||||
{"GetActorCell", ActorFunctions::GetActorCell},\
|
||||
{"GetActorRefId", ActorFunctions::GetActorRefId},\
|
||||
{"GetActorRefNumIndex", ActorFunctions::GetActorRefNumIndex},\
|
||||
{"GetActorMpNum", ActorFunctions::GetActorMpNum},\
|
||||
\
|
||||
{"GetActorPosX", ActorFunctions::GetActorPosX},\
|
||||
{"GetActorPosY", ActorFunctions::GetActorPosY},\
|
||||
{"GetActorPosZ", ActorFunctions::GetActorPosZ},\
|
||||
{"GetActorRotX", ActorFunctions::GetActorRotX},\
|
||||
{"GetActorRotY", ActorFunctions::GetActorRotY},\
|
||||
{"GetActorRotZ", ActorFunctions::GetActorRotZ},\
|
||||
\
|
||||
{"GetActorHealthBase", ActorFunctions::GetActorHealthBase},\
|
||||
{"GetActorHealthCurrent", ActorFunctions::GetActorHealthCurrent},\
|
||||
{"GetActorHealthModified", ActorFunctions::GetActorHealthModified},\
|
||||
{"GetActorMagickaBase", ActorFunctions::GetActorMagickaBase},\
|
||||
{"GetActorMagickaCurrent", ActorFunctions::GetActorMagickaCurrent},\
|
||||
{"GetActorMagickaModified", ActorFunctions::GetActorMagickaModified},\
|
||||
{"GetActorFatigueBase", ActorFunctions::GetActorFatigueBase},\
|
||||
{"GetActorFatigueCurrent", ActorFunctions::GetActorFatigueCurrent},\
|
||||
{"GetActorFatigueModified", ActorFunctions::GetActorFatigueModified},\
|
||||
\
|
||||
{"GetActorEquipmentItemRefId", ActorFunctions::GetActorEquipmentItemRefId},\
|
||||
{"GetActorEquipmentItemCount", ActorFunctions::GetActorEquipmentItemCount},\
|
||||
{"GetActorEquipmentItemCharge", ActorFunctions::GetActorEquipmentItemCharge},\
|
||||
\
|
||||
{"DoesActorHavePosition", ActorFunctions::DoesActorHavePosition},\
|
||||
{"DoesActorHaveStatsDynamic", ActorFunctions::DoesActorHaveStatsDynamic},\
|
||||
\
|
||||
{"SetActorListCell", ActorFunctions::SetActorListCell},\
|
||||
{"SetActorListAction", ActorFunctions::SetActorListAction},\
|
||||
\
|
||||
{"SetActorCell", ActorFunctions::SetActorCell},\
|
||||
{"SetActorRefId", ActorFunctions::SetActorRefId},\
|
||||
{"SetActorRefNumIndex", ActorFunctions::SetActorRefNumIndex},\
|
||||
{"SetActorMpNum", ActorFunctions::SetActorMpNum},\
|
||||
\
|
||||
{"SetActorPosition", ActorFunctions::SetActorPosition},\
|
||||
{"SetActorRotation", ActorFunctions::SetActorRotation},\
|
||||
\
|
||||
{"SetActorHealthBase", ActorFunctions::SetActorHealthBase},\
|
||||
{"SetActorHealthCurrent", ActorFunctions::SetActorHealthCurrent},\
|
||||
{"SetActorHealthModified", ActorFunctions::SetActorHealthModified},\
|
||||
{"SetActorMagickaBase", ActorFunctions::SetActorMagickaBase},\
|
||||
{"SetActorMagickaCurrent", ActorFunctions::SetActorMagickaCurrent},\
|
||||
{"SetActorMagickaModified", ActorFunctions::SetActorMagickaModified},\
|
||||
{"SetActorFatigueBase", ActorFunctions::SetActorFatigueBase},\
|
||||
{"SetActorFatigueCurrent", ActorFunctions::SetActorFatigueCurrent},\
|
||||
{"SetActorFatigueModified", ActorFunctions::SetActorFatigueModified},\
|
||||
\
|
||||
{"EquipActorItem", ActorFunctions::EquipActorItem},\
|
||||
{"UnequipActorItem", ActorFunctions::UnequipActorItem},\
|
||||
\
|
||||
{"AddActor", ActorFunctions::AddActor},\
|
||||
\
|
||||
{"SendActorList", ActorFunctions::SendActorList},\
|
||||
{"SendActorAuthority", ActorFunctions::SendActorAuthority},\
|
||||
{"SendActorPosition", ActorFunctions::SendActorPosition},\
|
||||
{"SendActorStatsDynamic", ActorFunctions::SendActorStatsDynamic},\
|
||||
{"SendActorEquipment", ActorFunctions::SendActorEquipment},\
|
||||
{"SendActorCellChange", ActorFunctions::SendActorCellChange}
|
||||
|
||||
class ActorFunctions
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* \brief Use the last actor list received by the server as the one being read.
|
||||
*
|
||||
* \return void
|
||||
*/
|
||||
static void ReadLastActorList() noexcept;
|
||||
|
||||
/**
|
||||
* \brief Use the temporary actor list stored for a cell as the one being read.
|
||||
*
|
||||
* This type of actor list is used to store actor positions and dynamic stats and is deleted
|
||||
* when the cell is unloaded.
|
||||
*
|
||||
* \param cellDescription The description of the cell whose actor list should be read.
|
||||
* \return void
|
||||
*/
|
||||
static void ReadCellActorList(const char* cellDescription) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Clear the data from the last actor list sent by the server.
|
||||
*
|
||||
* This is used to initialize the sending of new Actor packets.
|
||||
*
|
||||
* \param pid The player ID to whom the actor list should be attached.
|
||||
* \return void
|
||||
*/
|
||||
static void InitializeActorList(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the number of indexes in the read actor list.
|
||||
*
|
||||
* \return The number of indexes.
|
||||
*/
|
||||
static unsigned int GetActorListSize() noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the action type used in the read actor list.
|
||||
*
|
||||
* \return The action type (0 for SET, 1 for ADD, 2 for REMOVE, 3 for REQUEST).
|
||||
*/
|
||||
static unsigned char GetActorListAction() noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the cell description of the actor at a certain index in the read actor list.
|
||||
*
|
||||
* \param i The index of the actor.
|
||||
* \return The cell description.
|
||||
*/
|
||||
static const char *GetActorCell(unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the refId of the actor at a certain index in the read actor list.
|
||||
*
|
||||
* \param i The index of the actor.
|
||||
* \return The refId.
|
||||
*/
|
||||
static const char *GetActorRefId(unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the refNumIndex of the actor at a certain index in the read actor list.
|
||||
*
|
||||
* \param i The index of the actor.
|
||||
* \return The refNumIndex.
|
||||
*/
|
||||
static int GetActorRefNumIndex(unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the mpNum of the actor at a certain index in the read actor list.
|
||||
*
|
||||
* \param i The index of the actor.
|
||||
* \return The mpNum.
|
||||
*/
|
||||
static int GetActorMpNum(unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the X position of the actor at a certain index in the read actor list.
|
||||
*
|
||||
* \param i The index of the actor.
|
||||
* \return The X position.
|
||||
*/
|
||||
static double GetActorPosX(unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the Y position of the actor at a certain index in the read actor list.
|
||||
*
|
||||
* \param i The index of the actor.
|
||||
* \return The Y position.
|
||||
*/
|
||||
static double GetActorPosY(unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the Z position of the actor at a certain index in the read actor list.
|
||||
*
|
||||
* \param i The index of the actor.
|
||||
* \return The Z position.
|
||||
*/
|
||||
static double GetActorPosZ(unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the X rotation of the actor at a certain index in the read actor list.
|
||||
*
|
||||
* \param i The index of the actor.
|
||||
* \return The X rotation.
|
||||
*/
|
||||
static double GetActorRotX(unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the Y rotation of the actor at a certain index in the read actor list.
|
||||
*
|
||||
* \param i The index of the actor.
|
||||
* \return The Y rotation.
|
||||
*/
|
||||
static double GetActorRotY(unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the Z rotation of the actor at a certain index in the read actor list.
|
||||
*
|
||||
* \param i The index of the actor.
|
||||
* \return The Z rotation.
|
||||
*/
|
||||
static double GetActorRotZ(unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the base health of the actor at a certain index in the read actor list.
|
||||
*
|
||||
* \param i The index of the actor.
|
||||
* \return The base health.
|
||||
*/
|
||||
static double GetActorHealthBase(unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the current health of the actor at a certain index in the read actor list.
|
||||
*
|
||||
* \param i The index of the actor.
|
||||
* \return The current health.
|
||||
*/
|
||||
static double GetActorHealthCurrent(unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the modified health of the actor at a certain index in the read actor list.
|
||||
*
|
||||
* \param i The index of the actor.
|
||||
* \return The modified health.
|
||||
*/
|
||||
static double GetActorHealthModified(unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the base magicka of the actor at a certain index in the read actor list.
|
||||
*
|
||||
* \param i The index of the actor.
|
||||
* \return The base magicka.
|
||||
*/
|
||||
static double GetActorMagickaBase(unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the current magicka of the actor at a certain index in the read actor list.
|
||||
*
|
||||
* \param i The index of the actor.
|
||||
* \return The current magicka.
|
||||
*/
|
||||
static double GetActorMagickaCurrent(unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the modified magicka of the actor at a certain index in the read actor list.
|
||||
*
|
||||
* \param i The index of the actor.
|
||||
* \return The modified magicka.
|
||||
*/
|
||||
static double GetActorMagickaModified(unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the base fatigue of the actor at a certain index in the read actor list.
|
||||
*
|
||||
* \param i The index of the actor.
|
||||
* \return The base fatigue.
|
||||
*/
|
||||
static double GetActorFatigueBase(unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the current fatigue of the actor at a certain index in the read actor list.
|
||||
*
|
||||
* \param i The index of the actor.
|
||||
* \return The current fatigue.
|
||||
*/
|
||||
static double GetActorFatigueCurrent(unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the modified fatigue of the actor at a certain index in the read actor list.
|
||||
*
|
||||
* \param i The index of the actor.
|
||||
* \return The modified fatigue.
|
||||
*/
|
||||
static double GetActorFatigueModified(unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the refId of the item in a certain slot of the equipment of the actor at a
|
||||
* certain index in the read actor list.
|
||||
*
|
||||
* \param i The index of the actor.
|
||||
* \param slot The slot of the equipment item.
|
||||
* \return The refId.
|
||||
*/
|
||||
static const char *GetActorEquipmentItemRefId(unsigned int i, unsigned short slot) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the count of the item in a certain slot of the equipment of the actor at a
|
||||
* certain index in the read actor list.
|
||||
*
|
||||
* \param i The index of the actor.
|
||||
* \param slot The slot of the equipment item.
|
||||
* \return The item count.
|
||||
*/
|
||||
static int GetActorEquipmentItemCount(unsigned int i, unsigned short slot) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the charge of the item in a certain slot of the equipment of the actor at a
|
||||
* certain index in the read actor list.
|
||||
*
|
||||
* \param i The index of the actor.
|
||||
* \param slot The slot of the equipment item.
|
||||
* \return The charge.
|
||||
*/
|
||||
static int GetActorEquipmentItemCharge(unsigned int i, unsigned short slot) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Check whether there is any positional data for the actor at a certain index in
|
||||
* the read actor list.
|
||||
*
|
||||
* This is only useful when reading the actor list data recorded for a particular cell.
|
||||
*
|
||||
* \param i The index of the actor.
|
||||
* \return Whether the read actor list contains positional data.
|
||||
*/
|
||||
static bool DoesActorHavePosition(unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Check whether there is any dynamic stats data for the actor at a certain index in
|
||||
* the read actor list.
|
||||
*
|
||||
* This is only useful when reading the actor list data recorded for a particular cell.
|
||||
*
|
||||
* \param i The index of the actor.
|
||||
* \return Whether the read actor list contains dynamic stats data.
|
||||
*/
|
||||
static bool DoesActorHaveStatsDynamic(unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the cell of the temporary actor list stored on the server.
|
||||
*
|
||||
* The cell is determined to be an exterior cell if it fits the pattern of a number followed
|
||||
* by a comma followed by another number.
|
||||
*
|
||||
* \param cellDescription The description of the cell.
|
||||
* \return void
|
||||
*/
|
||||
static void SetActorListCell(const char* cellDescription) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the action type of the temporary actor list stored on the server.
|
||||
*
|
||||
* \param action The action type (0 for SET, 1 for ADD, 2 for REMOVE, 3 for REQUEST).
|
||||
* \return void
|
||||
*/
|
||||
static void SetActorListAction(unsigned char action) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the cell of the temporary actor stored on the server.
|
||||
*
|
||||
* Used for ActorCellChange packets, where a specific actor's cell now differs from that of the
|
||||
* actor list.
|
||||
*
|
||||
* The cell is determined to be an exterior cell if it fits the pattern of a number followed
|
||||
* by a comma followed by another number.
|
||||
*
|
||||
* \param cellDescription The description of the cell.
|
||||
* \return void
|
||||
*/
|
||||
static void SetActorCell(const char* cellDescription) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the refId of the temporary actor stored on the server.
|
||||
*
|
||||
* \param refId The refId.
|
||||
* \return void
|
||||
*/
|
||||
static void SetActorRefId(const char* refId) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the refNumIndex of the temporary actor stored on the server.
|
||||
*
|
||||
* \param refNumIndex The refNumIndex.
|
||||
* \return void
|
||||
*/
|
||||
static void SetActorRefNumIndex(int refNumIndex) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the mpNum of the temporary actor stored on the server.
|
||||
*
|
||||
* \param mpNum The mpNum.
|
||||
* \return void
|
||||
*/
|
||||
static void SetActorMpNum(int mpNum) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the position of the temporary actor stored on the server.
|
||||
*
|
||||
* \param x The X position.
|
||||
* \param y The Y position.
|
||||
* \param z The Z position.
|
||||
* \return void
|
||||
*/
|
||||
static void SetActorPosition(double x, double y, double z) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the rotation of the temporary actor stored on the server.
|
||||
*
|
||||
* \param x The X rotation.
|
||||
* \param y The Y rotation.
|
||||
* \param z The Z rotation.
|
||||
* \return void
|
||||
*/
|
||||
static void SetActorRotation(double x, double y, double z) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the base health of the temporary actor stored on the server.
|
||||
*
|
||||
* \param value The new value.
|
||||
* \return void
|
||||
*/
|
||||
static void SetActorHealthBase(double value) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the current health of the temporary actor stored on the server.
|
||||
*
|
||||
* \param value The new value.
|
||||
* \return void
|
||||
*/
|
||||
static void SetActorHealthCurrent(double value) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the modified health of the temporary actor stored on the server.
|
||||
*
|
||||
* \param value The new value.
|
||||
* \return void
|
||||
*/
|
||||
static void SetActorHealthModified(double value) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the base magicka of the temporary actor stored on the server.
|
||||
*
|
||||
* \param value The new value.
|
||||
* \return void
|
||||
*/
|
||||
static void SetActorMagickaBase(double value) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the current magicka of the temporary actor stored on the server.
|
||||
*
|
||||
* \param value The new value.
|
||||
* \return void
|
||||
*/
|
||||
static void SetActorMagickaCurrent(double value) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the modified magicka of the temporary actor stored on the server.
|
||||
*
|
||||
* \param value The new value.
|
||||
* \return void
|
||||
*/
|
||||
static void SetActorMagickaModified(double value) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the base fatigue of the temporary actor stored on the server.
|
||||
*
|
||||
* \param value The new value.
|
||||
* \return void
|
||||
*/
|
||||
static void SetActorFatigueBase(double value) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the current fatigue of the temporary actor stored on the server.
|
||||
*
|
||||
* \param value The new value.
|
||||
* \return void
|
||||
*/
|
||||
static void SetActorFatigueCurrent(double value) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the modified fatigue of the temporary actor stored on the server.
|
||||
*
|
||||
* \param value The new value.
|
||||
* \return void
|
||||
*/
|
||||
static void SetActorFatigueModified(double value) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Equip an item in a certain slot of the equipment of the temporary actor stored
|
||||
* on the server.
|
||||
*
|
||||
* \param slot The equipment slot.
|
||||
* \param refId The refId of the item.
|
||||
* \param count The count of the item.
|
||||
* \param charge The charge of the item.
|
||||
* \return void
|
||||
*/
|
||||
static void EquipActorItem(unsigned short slot, const char* refId, unsigned int count, int charge) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Unequip the item in a certain slot of the equipment of the temporary actor stored
|
||||
* on the server.
|
||||
*
|
||||
* \param slot The equipment slot.
|
||||
* \return void
|
||||
*/
|
||||
static void UnequipActorItem(unsigned short slot) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Add a copy of the server's temporary actor to the server's temporary actor list.
|
||||
*
|
||||
* In the process, the server's temporary actor will automatically be cleared so a new
|
||||
* one can be set up.
|
||||
*
|
||||
* \return void
|
||||
*/
|
||||
static void AddActor() noexcept;
|
||||
|
||||
/**
|
||||
* \brief Send an ActorList packet.
|
||||
*
|
||||
* It is sent only to the player for whom the current actor list was initialized.
|
||||
*
|
||||
* \return void
|
||||
*/
|
||||
static void SendActorList() noexcept;
|
||||
|
||||
/**
|
||||
* \brief Send an ActorAuthority packet.
|
||||
*
|
||||
* The player for whom the current actor list was initialized is recorded in the server memory
|
||||
* as the new actor authority for the actor list's cell.
|
||||
*
|
||||
* The packet is sent to that player as well as all other players who have the cell loaded.
|
||||
*
|
||||
* \return void
|
||||
*/
|
||||
static void SendActorAuthority() noexcept;
|
||||
|
||||
/**
|
||||
* \brief Send an ActorPosition packet.
|
||||
*
|
||||
* It is sent only to the player for whom the current actor list was initialized.
|
||||
*
|
||||
* \return void
|
||||
*/
|
||||
static void SendActorPosition() noexcept;
|
||||
|
||||
/**
|
||||
* \brief Send an ActorStatsDynamic packet.
|
||||
*
|
||||
* It is sent only to the player for whom the current actor list was initialized.
|
||||
*
|
||||
* \return void
|
||||
*/
|
||||
static void SendActorStatsDynamic() noexcept;
|
||||
|
||||
/**
|
||||
* \brief Send an ActorEquipment packet.
|
||||
*
|
||||
* It is sent only to the player for whom the current actor list was initialized.
|
||||
*
|
||||
* \return void
|
||||
*/
|
||||
static void SendActorEquipment() noexcept;
|
||||
|
||||
/**
|
||||
* \brief Send an ActorCellChange packet.
|
||||
*
|
||||
* It is sent only to the player for whom the current actor list was initialized.
|
||||
*
|
||||
* \return void
|
||||
*/
|
||||
static void SendActorCellChange() noexcept;
|
||||
};
|
||||
|
||||
|
||||
#endif //OPENMW_ACTORAPI_HPP
|
@ -1,53 +0,0 @@
|
||||
#include "Books.hpp"
|
||||
#include <apps/openmw-mp/Script/ScriptFunctions.hpp>
|
||||
#include <components/openmw-mp/NetworkMessages.hpp>
|
||||
#include <apps/openmw-mp/Networking.hpp>
|
||||
|
||||
using namespace mwmp;
|
||||
|
||||
void BookFunctions::InitializeBookChanges(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
return player->bookChanges.books.clear();
|
||||
}
|
||||
|
||||
unsigned int BookFunctions::GetBookChangesSize(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
return player->bookChanges.count;
|
||||
}
|
||||
|
||||
void BookFunctions::AddBook(unsigned short pid, const char* bookId) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
mwmp::Book book;
|
||||
book.bookId = bookId;
|
||||
|
||||
player->bookChanges.books.push_back(book);
|
||||
}
|
||||
|
||||
const char *BookFunctions::GetBookId(unsigned short pid, unsigned int i) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, "");
|
||||
|
||||
if (i >= player->bookChanges.count)
|
||||
return "invalid";
|
||||
|
||||
return player->bookChanges.books.at(i).bookId.c_str();
|
||||
}
|
||||
|
||||
void BookFunctions::SendBookChanges(unsigned short pid, bool toOthers) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_BOOK)->setPlayer(player);
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_BOOK)->Send(toOthers);
|
||||
}
|
@ -1,69 +0,0 @@
|
||||
#ifndef OPENMW_BOOKAPI_HPP
|
||||
#define OPENMW_BOOKAPI_HPP
|
||||
|
||||
#define BOOKAPI \
|
||||
{"InitializeBookChanges", BookFunctions::InitializeBookChanges},\
|
||||
\
|
||||
{"GetBookChangesSize", BookFunctions::GetBookChangesSize},\
|
||||
\
|
||||
{"AddBook", BookFunctions::AddBook},\
|
||||
\
|
||||
{"GetBookId", BookFunctions::GetBookId},\
|
||||
\
|
||||
{"SendBookChanges", BookFunctions::SendBookChanges}
|
||||
|
||||
class BookFunctions
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* \brief Clear the last recorded book changes for a player.
|
||||
*
|
||||
* This is used to initialize the sending of new PlayerBook packets.
|
||||
*
|
||||
* \param pid The player ID whose book changes should be used.
|
||||
* \return void
|
||||
*/
|
||||
static void InitializeBookChanges(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the number of indexes in a player's latest book changes.
|
||||
*
|
||||
* \param pid The player ID whose book changes should be used.
|
||||
* \return The number of indexes.
|
||||
*/
|
||||
static unsigned int GetBookChangesSize(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Add a new book to the book changes for a player.
|
||||
*
|
||||
* \param pid The player ID whose book changes should be used.
|
||||
* \param bookId The bookId of the book.
|
||||
* \return void
|
||||
*/
|
||||
static void AddBook(unsigned short pid, const char* bookId) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the bookId at a certain index in a player's latest book changes.
|
||||
*
|
||||
* \param pid The player ID whose book changes should be used.
|
||||
* \param i The index of the book.
|
||||
* \return The bookId.
|
||||
*/
|
||||
static const char *GetBookId(unsigned short pid, unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Send a PlayerBook packet with a player's recorded book changes.
|
||||
*
|
||||
* \param pid The player ID whose book changes should be used.
|
||||
* \param toOthers Whether this packet should be sent only to other players or
|
||||
* only to the player it is about.
|
||||
* \return void
|
||||
*/
|
||||
static void SendBookChanges(unsigned short pid, bool toOthers = false) noexcept;
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
#endif //OPENMW_BOOKAPI_HPP
|
@ -1,149 +0,0 @@
|
||||
#include "Cells.hpp"
|
||||
#include <apps/openmw-mp/Script/ScriptFunctions.hpp>
|
||||
#include <components/openmw-mp/NetworkMessages.hpp>
|
||||
#include <apps/openmw-mp/Player.hpp>
|
||||
#include <apps/openmw-mp/Networking.hpp>
|
||||
#include <components/openmw-mp/Log.hpp>
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
static std::string tempCellDescription;
|
||||
|
||||
void CellFunctions::InitializeMapChanges(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
player->mapChanges.cellsExplored.clear();
|
||||
}
|
||||
|
||||
unsigned int CellFunctions::GetCellStateChangesSize(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
return player->cellStateChanges.count;
|
||||
}
|
||||
|
||||
unsigned int CellFunctions::GetCellStateType(unsigned short pid, unsigned int i) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
return player->cellStateChanges.cellStates.at(i).type;
|
||||
}
|
||||
|
||||
const char *CellFunctions::GetCellStateDescription(unsigned short pid, unsigned int i) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, "");
|
||||
|
||||
if (i >= player->cellStateChanges.count)
|
||||
return "invalid";
|
||||
|
||||
tempCellDescription = player->cellStateChanges.cellStates.at(i).cell.getDescription();
|
||||
return tempCellDescription.c_str();
|
||||
}
|
||||
|
||||
const char *CellFunctions::GetCell(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
tempCellDescription = player->cell.getDescription().c_str();
|
||||
return tempCellDescription.c_str();
|
||||
}
|
||||
|
||||
int CellFunctions::GetExteriorX(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
return player->cell.mData.mX;
|
||||
}
|
||||
|
||||
int CellFunctions::GetExteriorY(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
return player->cell.mData.mY;
|
||||
}
|
||||
|
||||
bool CellFunctions::IsInExterior(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, false);
|
||||
|
||||
return player->cell.isExterior();
|
||||
}
|
||||
|
||||
const char *CellFunctions::GetRegion(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
return player->cell.mRegion.c_str();
|
||||
}
|
||||
|
||||
bool CellFunctions::IsChangingRegion(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, false);
|
||||
|
||||
return player->isChangingRegion;
|
||||
}
|
||||
|
||||
void CellFunctions::SetCell(unsigned short pid, const char *cellDescription) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
|
||||
LOG_MESSAGE_SIMPLE(Log::LOG_INFO, "Script is moving %s from %s to %s", player->npc.mName.c_str(),
|
||||
player->cell.getDescription().c_str(), cellDescription);
|
||||
|
||||
player->cell = Utils::getCellFromDescription(cellDescription);
|
||||
}
|
||||
|
||||
void CellFunctions::SetExteriorCell(unsigned short pid, int x, int y) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
|
||||
LOG_MESSAGE_SIMPLE(Log::LOG_INFO, "Script is moving %s from %s to %i,%i", player->npc.mName.c_str(),
|
||||
player->cell.getDescription().c_str(), x, y);
|
||||
|
||||
// If the player is currently in an interior, turn off the interior flag
|
||||
// from the cell
|
||||
if (!player->cell.isExterior())
|
||||
player->cell.mData.mFlags &= ~ESM::Cell::Interior;
|
||||
|
||||
player->cell.mData.mX = x;
|
||||
player->cell.mData.mY = y;
|
||||
}
|
||||
|
||||
void CellFunctions::AddCellExplored(unsigned short pid, const char* cellDescription) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
ESM::Cell cellExplored = Utils::getCellFromDescription(cellDescription);
|
||||
player->mapChanges.cellsExplored.push_back(cellExplored);
|
||||
}
|
||||
|
||||
void CellFunctions::SendCell(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_CELL_CHANGE)->setPlayer(player);
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_CELL_CHANGE)->Send(false);
|
||||
}
|
||||
|
||||
void CellFunctions::SendMapChanges(unsigned short pid, bool toOthers) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_MAP)->setPlayer(player);
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_MAP)->Send(toOthers);
|
||||
}
|
@ -1,179 +0,0 @@
|
||||
#ifndef OPENMW_CELLAPI_HPP
|
||||
#define OPENMW_CELLAPI_HPP
|
||||
|
||||
#include "../Types.hpp"
|
||||
|
||||
#define CELLAPI \
|
||||
{"InitializeMapChanges", CellFunctions::InitializeMapChanges},\
|
||||
\
|
||||
{"GetCellStateChangesSize", CellFunctions::GetCellStateChangesSize},\
|
||||
\
|
||||
{"GetCellStateType", CellFunctions::GetCellStateType},\
|
||||
{"GetCellStateDescription", CellFunctions::GetCellStateDescription},\
|
||||
\
|
||||
{"GetCell", CellFunctions::GetCell},\
|
||||
{"GetExteriorX", CellFunctions::GetExteriorX},\
|
||||
{"GetExteriorY", CellFunctions::GetExteriorY},\
|
||||
{"IsInExterior", CellFunctions::IsInExterior},\
|
||||
\
|
||||
{"GetRegion", CellFunctions::GetRegion},\
|
||||
{"IsChangingRegion", CellFunctions::IsChangingRegion},\
|
||||
\
|
||||
{"SetCell", CellFunctions::SetCell},\
|
||||
{"SetExteriorCell", CellFunctions::SetExteriorCell},\
|
||||
\
|
||||
{"AddCellExplored", CellFunctions::AddCellExplored},\
|
||||
\
|
||||
{"SendCell", CellFunctions::SendCell},\
|
||||
{"SendMapChanges", CellFunctions::SendMapChanges}
|
||||
|
||||
|
||||
class CellFunctions
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* \brief Clear the last recorded map changes for a player.
|
||||
*
|
||||
* This is used to initialize the sending of new PlayerMap packets.
|
||||
*
|
||||
* \param pid The player ID whose map changes should be used.
|
||||
* \return void
|
||||
*/
|
||||
static void InitializeMapChanges(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the number of indexes in a player's latest cell state changes.
|
||||
*
|
||||
* \param pid The player ID whose cell state changes should be used.
|
||||
* \return The number of indexes.
|
||||
*/
|
||||
static unsigned int GetCellStateChangesSize(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the cell state type at a certain index in a player's latest cell state changes.
|
||||
*
|
||||
* \param pid The player ID whose cell state changes should be used.
|
||||
* \param i The index of the cell state.
|
||||
* \return The cell state type (0 for LOAD, 1 for UNLOAD).
|
||||
*/
|
||||
static unsigned int GetCellStateType(unsigned short pid, unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the cell description at a certain index in a player's latest cell state changes.
|
||||
*
|
||||
* \param pid The player ID whose cell state changes should be used.
|
||||
* \param i The index of the cell state.
|
||||
* \return The cell description.
|
||||
*/
|
||||
static const char *GetCellStateDescription(unsigned short pid, unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the cell description of a player's cell.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \return The cell description.
|
||||
*/
|
||||
static const char *GetCell(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the X coordinate of the player's exterior cell.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \return The X coordinate of the cell.
|
||||
*/
|
||||
static int GetExteriorX(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the Y coordinate of the player's exterior cell.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \return The Y coordinate of the cell.
|
||||
*/
|
||||
static int GetExteriorY(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Check whether the player is in an exterior cell or not.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \return Whether the player is in an exterior cell.
|
||||
*/
|
||||
static bool IsInExterior(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the region of the player's exterior cell.
|
||||
*
|
||||
* A blank value will be returned if the player is in an interior.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \return The region.
|
||||
*/
|
||||
static const char *GetRegion(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Check whether the player's last cell change has involved a region change.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \return Whether the player has changed their region.
|
||||
*/
|
||||
static bool IsChangingRegion(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the cell of a player.
|
||||
*
|
||||
* This changes the cell recorded for that player in the server memory, but does not by itself
|
||||
* send a packet.
|
||||
*
|
||||
* The cell is determined to be an exterior cell if it fits the pattern of a number followed
|
||||
* by a comma followed by another number.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \param cellDescription The cell description.
|
||||
* \return void
|
||||
*/
|
||||
static void SetCell(unsigned short pid, const char *cellDescription) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the cell of a player to an exterior cell.
|
||||
*
|
||||
* This changes the cell recorded for that player in the server memory, but does not by itself
|
||||
* send a packet.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \param x The X coordinate of the cell.
|
||||
* \param y The Y coordinate of the cell.
|
||||
* \return void
|
||||
*/
|
||||
static void SetExteriorCell(unsigned short pid, int x, int y) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Add a new explored cell to the map changes for a player.
|
||||
*
|
||||
* \param pid The player ID whose map changes should be used.
|
||||
* \param cellDescription The cell description of the explored cell.
|
||||
* \return void
|
||||
*/
|
||||
static void AddCellExplored(unsigned short pid, const char* cellDescription) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Send a PlayerCellChange packet about a player.
|
||||
*
|
||||
* It is only sent to the affected player.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \return void
|
||||
*/
|
||||
static void SendCell(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Send a PlayerMap packet with a player's recorded map changes.
|
||||
*
|
||||
* \param pid The player ID whose map changes should be used.
|
||||
* \param toOthers Whether this packet should be sent only to other players or
|
||||
* only to the player it is about.
|
||||
* \return void
|
||||
*/
|
||||
static void SendMapChanges(unsigned short pid, bool toOthers = false) noexcept;
|
||||
};
|
||||
|
||||
#endif //OPENMW_CELLAPI_HPP
|
@ -1,135 +0,0 @@
|
||||
//
|
||||
// Created by koncord on 29.08.16.
|
||||
//
|
||||
|
||||
#include "CharClass.hpp"
|
||||
#include <apps/openmw-mp/Networking.hpp>
|
||||
#include <apps/openmw-mp/Script/ScriptFunctions.hpp>
|
||||
#include <components/openmw-mp/NetworkMessages.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace ESM;
|
||||
|
||||
const char *CharClassFunctions::GetDefaultClass(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, "");
|
||||
return player->charClass.mId.c_str();
|
||||
}
|
||||
|
||||
const char *CharClassFunctions::GetClassName(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, "");
|
||||
return player->charClass.mName.c_str();
|
||||
}
|
||||
|
||||
const char *CharClassFunctions::GetClassDesc(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, "");
|
||||
return player->charClass.mDescription.c_str();
|
||||
}
|
||||
|
||||
int CharClassFunctions::GetClassMajorAttribute(unsigned short pid, unsigned char slot) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
if (slot > 1)
|
||||
throw invalid_argument("Incorrect attribute slot id");
|
||||
return player->charClass.mData.mAttribute[slot];
|
||||
}
|
||||
|
||||
int CharClassFunctions::GetClassSpecialization(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
return player->charClass.mData.mSpecialization;
|
||||
}
|
||||
|
||||
int CharClassFunctions::GetClassMajorSkill(unsigned short pid, unsigned char slot) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
if (slot > 4)
|
||||
throw invalid_argument("Incorrect skill slot id");
|
||||
return player->charClass.mData.mSkills[slot][1];
|
||||
}
|
||||
|
||||
int CharClassFunctions::GetClassMinorSkill(unsigned short pid, unsigned char slot) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
if (slot > 4)
|
||||
throw invalid_argument("Incorrect skill slot id");
|
||||
return player->charClass.mData.mSkills[slot][0];
|
||||
}
|
||||
|
||||
int CharClassFunctions::IsClassDefault(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
return !player->charClass.mId.empty(); // true if default
|
||||
}
|
||||
|
||||
void CharClassFunctions::SetDefaultClass(unsigned short pid, const char *id) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
player->charClass.mId = id;
|
||||
}
|
||||
void CharClassFunctions::SetClassName(unsigned short pid, const char *name) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
player->charClass.mName = name;
|
||||
player->charClass.mId = "";
|
||||
}
|
||||
void CharClassFunctions::SetClassDesc(unsigned short pid, const char *desc) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
player->charClass.mDescription = desc;
|
||||
}
|
||||
void CharClassFunctions::SetClassMajorAttribute(unsigned short pid, unsigned char slot, int attrId) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
|
||||
if (slot > 1)
|
||||
throw invalid_argument("Incorrect attribute slot id");
|
||||
|
||||
player->charClass.mData.mAttribute[slot] = attrId;
|
||||
|
||||
}
|
||||
void CharClassFunctions::SetClassSpecialization(unsigned short pid, int spec) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
player->charClass.mData.mSpecialization = spec;
|
||||
}
|
||||
void CharClassFunctions::SetClassMajorSkill(unsigned short pid, unsigned char slot, int skillId) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
if (slot > 4)
|
||||
throw invalid_argument("Incorrect skill slot id");
|
||||
player->charClass.mData.mSkills[slot][1] = skillId;
|
||||
}
|
||||
void CharClassFunctions::SetClassMinorSkill(unsigned short pid, unsigned char slot, int skillId) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
if (slot > 4)
|
||||
throw invalid_argument("Incorrect skill slot id");
|
||||
player->charClass.mData.mSkills[slot][0] = skillId;
|
||||
}
|
||||
|
||||
void CharClassFunctions::SendClass(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_CHARCLASS)->setPlayer(player);
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_CHARCLASS)->Send(false);
|
||||
}
|
@ -1,181 +0,0 @@
|
||||
//
|
||||
// Created by koncord on 29.08.16.
|
||||
//
|
||||
|
||||
#ifndef OPENMW_CHARCLASSAPI_HPP
|
||||
#define OPENMW_CHARCLASSAPI_HPP
|
||||
|
||||
#include "../Types.hpp"
|
||||
|
||||
#define CHARCLASSAPI \
|
||||
{"GetDefaultClass", CharClassFunctions::GetDefaultClass},\
|
||||
{"GetClassName", CharClassFunctions::GetClassName},\
|
||||
{"GetClassDesc", CharClassFunctions::GetClassDesc},\
|
||||
{"GetClassMajorAttribute", CharClassFunctions::GetClassMajorAttribute},\
|
||||
{"GetClassSpecialization", CharClassFunctions::GetClassSpecialization},\
|
||||
{"GetClassMajorSkill", CharClassFunctions::GetClassMajorSkill},\
|
||||
{"GetClassMinorSkill", CharClassFunctions::GetClassMinorSkill},\
|
||||
{"IsClassDefault", CharClassFunctions::IsClassDefault},\
|
||||
\
|
||||
{"SetDefaultClass", CharClassFunctions::SetDefaultClass},\
|
||||
{"SetClassName", CharClassFunctions::SetClassName},\
|
||||
{"SetClassDesc", CharClassFunctions::SetClassDesc},\
|
||||
{"SetClassMajorAttribute", CharClassFunctions::SetClassMajorAttribute},\
|
||||
{"SetClassSpecialization", CharClassFunctions::SetClassSpecialization},\
|
||||
{"SetClassMajorSkill", CharClassFunctions::SetClassMajorSkill},\
|
||||
{"SetClassMinorSkill", CharClassFunctions::SetClassMinorSkill},\
|
||||
\
|
||||
{"SendClass", CharClassFunctions::SendClass}
|
||||
|
||||
|
||||
class CharClassFunctions
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* \brief Get the default class used by a player.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \return The ID of the default class.
|
||||
*/
|
||||
static const char *GetDefaultClass(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the name of the custom class used by a player.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \return The name of the custom class.
|
||||
*/
|
||||
static const char *GetClassName(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the description of the custom class used by a player.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \return The description of the custom class.
|
||||
*/
|
||||
static const char *GetClassDesc(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the ID of one of the two major attributes of a custom class used by a player.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \param slot The slot of the major attribute (0 or 1).
|
||||
* \return The ID of the major attribute.
|
||||
*/
|
||||
static int GetClassMajorAttribute(unsigned short pid, unsigned char slot) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the specialization ID of the custom class used by a player.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \return The specialization ID of the custom class (0 for Combat, 1 for Magic, 2 for Stealth).
|
||||
*/
|
||||
static int GetClassSpecialization(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the ID of one of the five major skills of a custom class used by a player.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \param slot The slot of the major skill (0 to 4).
|
||||
* \return The ID of the major skill.
|
||||
*/
|
||||
static int GetClassMajorSkill(unsigned short pid, unsigned char slot) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the ID of one of the five minor skills of a custom class used by a player.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \param slot The slot of the minor skill (0 to 4).
|
||||
* \return The ID of the minor skill.
|
||||
*/
|
||||
static int GetClassMinorSkill(unsigned short pid, unsigned char slot) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Check whether the player is using a default class instead of a custom one.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \return Whether the player is using a default class.
|
||||
*/
|
||||
static int IsClassDefault(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the default class used by a player.
|
||||
*
|
||||
* If this is left blank, the custom class data set for the player will be used instead.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \param id The ID of the default class.
|
||||
* \return void
|
||||
*/
|
||||
static void SetDefaultClass(unsigned short pid, const char *id) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the name of the custom class used by a player.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \param name The name of the custom class.
|
||||
* \return void
|
||||
*/
|
||||
static void SetClassName(unsigned short pid, const char *name) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the description of the custom class used by a player.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \param desc The description of the custom class.
|
||||
* \return void
|
||||
*/
|
||||
static void SetClassDesc(unsigned short pid, const char *desc) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the ID of one of the two major attributes of the custom class used by a player.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \param slot The slot of the major attribute (0 or 1).
|
||||
* \param attrId The ID to use for the attribute.
|
||||
* \return void
|
||||
*/
|
||||
static void SetClassMajorAttribute(unsigned short pid, unsigned char slot, int attrId) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the specialization of the custom class used by a player.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \param spec The specialization ID to use (0 for Combat, 1 for Magic, 2 for Stealth).
|
||||
* \return void
|
||||
*/
|
||||
static void SetClassSpecialization(unsigned short pid, int spec) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the ID of one of the five major skills of the custom class used by a player.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \param slot The slot of the major skill (0 to 4).
|
||||
* \param skillId The ID to use for the skill.
|
||||
* \return void
|
||||
*/
|
||||
static void SetClassMajorSkill(unsigned short pid, unsigned char slot, int skillId) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the ID of one of the five minor skills of the custom class used by a player.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \param slot The slot of the minor skill (0 to 4).
|
||||
* \param skillId The ID to use for the skill.
|
||||
* \return void
|
||||
*/
|
||||
static void SetClassMinorSkill(unsigned short pid, unsigned char slot, int skillId) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Send a PlayerCharClass packet about a player.
|
||||
*
|
||||
* It is only sent to the affected player.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \return void
|
||||
*/
|
||||
static void SendClass(unsigned short pid) noexcept;
|
||||
};
|
||||
|
||||
#endif //OPENMW_CHARCLASSAPI_HPP
|
@ -1,46 +0,0 @@
|
||||
//
|
||||
// Created by koncord on 29.04.16.
|
||||
//
|
||||
|
||||
#include <apps/openmw-mp/Script/ScriptFunctions.hpp>
|
||||
#include <apps/openmw-mp/Networking.hpp>
|
||||
#include <components/openmw-mp/NetworkMessages.hpp>
|
||||
|
||||
void ScriptFunctions::SendMessage(unsigned short pid, const char *message, bool broadcast) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
|
||||
player->chatMessage = message;
|
||||
|
||||
LOG_MESSAGE_SIMPLE(Log::LOG_VERBOSE, "System: %s", message);
|
||||
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_CHAT_MESSAGE)->setPlayer(player);
|
||||
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_CHAT_MESSAGE)->Send(false);
|
||||
if (broadcast)
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_CHAT_MESSAGE)->Send(true);
|
||||
}
|
||||
|
||||
void ScriptFunctions::CleanChatByPid(unsigned short pid)
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
|
||||
player->chatMessage.clear();
|
||||
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_CHAT_MESSAGE)->setPlayer(player);
|
||||
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_CHAT_MESSAGE)->Send(false);
|
||||
}
|
||||
|
||||
void ScriptFunctions::CleanChat()
|
||||
{
|
||||
for (auto player : *Players::getPlayers())
|
||||
{
|
||||
player.second->chatMessage.clear();
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_CHAT_MESSAGE)->setPlayer(player.second);
|
||||
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_CHAT_MESSAGE)->Send(false);
|
||||
}
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
#include "Dialogue.hpp"
|
||||
#include <apps/openmw-mp/Script/ScriptFunctions.hpp>
|
||||
#include <components/openmw-mp/NetworkMessages.hpp>
|
||||
#include <apps/openmw-mp/Networking.hpp>
|
||||
|
||||
using namespace mwmp;
|
||||
|
||||
void DialogueFunctions::InitializeTopicChanges(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
player->topicChanges.topics.clear();
|
||||
}
|
||||
|
||||
unsigned int DialogueFunctions::GetTopicChangesSize(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
return player->topicChanges.count;
|
||||
}
|
||||
|
||||
void DialogueFunctions::AddTopic(unsigned short pid, const char* topicId) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
mwmp::Topic topic;
|
||||
topic.topicId = topicId;
|
||||
|
||||
player->topicChanges.topics.push_back(topic);
|
||||
}
|
||||
|
||||
const char *DialogueFunctions::GetTopicId(unsigned short pid, unsigned int i) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, "");
|
||||
|
||||
if (i >= player->topicChanges.count)
|
||||
return "invalid";
|
||||
|
||||
return player->topicChanges.topics.at(i).topicId.c_str();
|
||||
}
|
||||
|
||||
void DialogueFunctions::SendTopicChanges(unsigned short pid, bool toOthers) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_TOPIC)->setPlayer(player);
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_TOPIC)->Send(toOthers);
|
||||
}
|
@ -1,68 +0,0 @@
|
||||
#ifndef OPENMW_DIALOGUEAPI_HPP
|
||||
#define OPENMW_DIALOGUEAPI_HPP
|
||||
|
||||
#define DIALOGUEAPI \
|
||||
{"InitializeTopicChanges", DialogueFunctions::InitializeTopicChanges},\
|
||||
\
|
||||
{"GetTopicChangesSize", DialogueFunctions::GetTopicChangesSize},\
|
||||
\
|
||||
{"AddTopic", DialogueFunctions::AddTopic},\
|
||||
\
|
||||
{"GetTopicId", DialogueFunctions::GetTopicId},\
|
||||
\
|
||||
{"SendTopicChanges", DialogueFunctions::SendTopicChanges}
|
||||
|
||||
class DialogueFunctions
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* \brief Clear the last recorded topic changes for a player.
|
||||
*
|
||||
* This is used to initialize the sending of new PlayerTopic packets.
|
||||
*
|
||||
* \param pid The player ID whose topic changes should be used.
|
||||
* \return void
|
||||
*/
|
||||
static void InitializeTopicChanges(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the number of indexes in a player's latest topic changes.
|
||||
*
|
||||
* \param pid The player ID whose topic changes should be used.
|
||||
* \return The number of indexes.
|
||||
*/
|
||||
static unsigned int GetTopicChangesSize(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Add a new topic to the topic changes for a player.
|
||||
*
|
||||
* \param pid The player ID whose topic changes should be used.
|
||||
* \param topicId The topicId of the topic.
|
||||
* \return void
|
||||
*/
|
||||
static void AddTopic(unsigned short pid, const char* topicId) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the topicId at a certain index in a player's latest topic changes.
|
||||
*
|
||||
* \param pid The player ID whose topic changes should be used.
|
||||
* \param i The index of the topic.
|
||||
* \return The topicId.
|
||||
*/
|
||||
static const char *GetTopicId(unsigned short pid, unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Send a PlayerTopic packet with a player's recorded topic changes.
|
||||
*
|
||||
* \param pid The player ID whose topic changes should be used.
|
||||
* \param toOthers Whether this packet should be sent only to other players or
|
||||
* only to the player it is about.
|
||||
* \return void
|
||||
*/
|
||||
static void SendTopicChanges(unsigned short pid, bool toOthers = false) noexcept;
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
#endif //OPENMW_DIALOGUEAPI_HPP
|
@ -1,116 +0,0 @@
|
||||
#include "Factions.hpp"
|
||||
#include <apps/openmw-mp/Script/ScriptFunctions.hpp>
|
||||
#include <components/openmw-mp/NetworkMessages.hpp>
|
||||
#include <apps/openmw-mp/Networking.hpp>
|
||||
#include <components/misc/stringops.hpp>
|
||||
|
||||
using namespace mwmp;
|
||||
|
||||
Faction tempFaction;
|
||||
const Faction emptyFaction = {};
|
||||
|
||||
void FactionFunctions::InitializeFactionChanges(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
player->factionChanges.factions.clear();
|
||||
}
|
||||
|
||||
unsigned int FactionFunctions::GetFactionChangesSize(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
return player->factionChanges.count;
|
||||
}
|
||||
|
||||
unsigned char FactionFunctions::GetFactionChangesAction(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
return player->factionChanges.action;
|
||||
}
|
||||
|
||||
const char *FactionFunctions::GetFactionId(unsigned short pid, unsigned int i) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, "");
|
||||
|
||||
if (i >= player->factionChanges.count)
|
||||
return "invalid";
|
||||
|
||||
return player->factionChanges.factions.at(i).factionId.c_str();
|
||||
}
|
||||
|
||||
int FactionFunctions::GetFactionRank(unsigned short pid, unsigned int i) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
return player->factionChanges.factions.at(i).rank;
|
||||
}
|
||||
|
||||
bool FactionFunctions::GetFactionExpulsionState(unsigned short pid, unsigned int i) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, false);
|
||||
|
||||
return player->factionChanges.factions.at(i).isExpelled;
|
||||
}
|
||||
|
||||
int FactionFunctions::GetFactionReputation(unsigned short pid, unsigned int i) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
return player->factionChanges.factions.at(i).reputation;
|
||||
}
|
||||
|
||||
void FactionFunctions::SetFactionChangesAction(unsigned short pid, unsigned char action) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
player->factionChanges.action = action;
|
||||
}
|
||||
|
||||
void FactionFunctions::SetFactionId(const char* factionId) noexcept
|
||||
{
|
||||
tempFaction.factionId = factionId;
|
||||
}
|
||||
|
||||
void FactionFunctions::SetFactionRank(unsigned int rank) noexcept
|
||||
{
|
||||
tempFaction.rank = rank;
|
||||
}
|
||||
|
||||
void FactionFunctions::SetFactionExpulsionState(bool expulsionState) noexcept
|
||||
{
|
||||
tempFaction.isExpelled = expulsionState;
|
||||
}
|
||||
|
||||
void FactionFunctions::SetFactionReputation(int reputation) noexcept
|
||||
{
|
||||
tempFaction.reputation = reputation;
|
||||
}
|
||||
|
||||
void FactionFunctions::AddFaction(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
player->factionChanges.factions.push_back(tempFaction);
|
||||
|
||||
tempFaction = emptyFaction;
|
||||
}
|
||||
|
||||
void FactionFunctions::SendFactionChanges(unsigned short pid, bool toOthers) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_FACTION)->setPlayer(player);
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_FACTION)->Send(toOthers);
|
||||
}
|
@ -1,156 +0,0 @@
|
||||
#ifndef OPENMW_FACTIONAPI_HPP
|
||||
#define OPENMW_FACTIONAPI_HPP
|
||||
|
||||
#define FACTIONAPI \
|
||||
{"InitializeFactionChanges", FactionFunctions::InitializeFactionChanges},\
|
||||
\
|
||||
{"GetFactionChangesSize", FactionFunctions::GetFactionChangesSize},\
|
||||
{"GetFactionChangesAction", FactionFunctions::GetFactionChangesAction},\
|
||||
\
|
||||
{"GetFactionId", FactionFunctions::GetFactionId},\
|
||||
{"GetFactionRank", FactionFunctions::GetFactionRank},\
|
||||
{"GetFactionExpulsionState", FactionFunctions::GetFactionExpulsionState},\
|
||||
{"GetFactionReputation", FactionFunctions::GetFactionReputation},\
|
||||
\
|
||||
{"SetFactionChangesAction", FactionFunctions::SetFactionChangesAction},\
|
||||
{"SetFactionId", FactionFunctions::SetFactionId},\
|
||||
{"SetFactionRank", FactionFunctions::SetFactionRank},\
|
||||
{"SetFactionExpulsionState", FactionFunctions::SetFactionExpulsionState},\
|
||||
{"SetFactionReputation", FactionFunctions::SetFactionReputation},\
|
||||
\
|
||||
{"AddFaction", FactionFunctions::AddFaction},\
|
||||
\
|
||||
{"SendFactionChanges", FactionFunctions::SendFactionChanges}
|
||||
|
||||
class FactionFunctions
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* \brief Clear the last recorded faction changes for a player.
|
||||
*
|
||||
* This is used to initialize the sending of new PlayerFaction packets.
|
||||
*
|
||||
* \param pid The player ID whose faction changes should be used.
|
||||
* \return void
|
||||
*/
|
||||
static void InitializeFactionChanges(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the number of indexes in a player's latest faction changes.
|
||||
*
|
||||
* \param pid The player ID whose faction changes should be used.
|
||||
* \return The number of indexes.
|
||||
*/
|
||||
static unsigned int GetFactionChangesSize(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the action type used in a player's latest faction changes.
|
||||
*
|
||||
* \param pid The player ID whose faction changes should be used.
|
||||
* \return The action type (0 for RANK, 1 for EXPULSION, 2 for REPUTATION).
|
||||
*/
|
||||
static unsigned char GetFactionChangesAction(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the factionId at a certain index in a player's latest faction changes.
|
||||
*
|
||||
* \param pid The player ID whose faction changes should be used.
|
||||
* \param i The index of the faction.
|
||||
* \return The factionId.
|
||||
*/
|
||||
static const char *GetFactionId(unsigned short pid, unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the rank at a certain index in a player's latest faction changes.
|
||||
*
|
||||
* \param pid The player ID whose faction changes should be used.
|
||||
* \param i The index of the faction.
|
||||
* \return The rank.
|
||||
*/
|
||||
static int GetFactionRank(unsigned short pid, unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the expulsion state at a certain index in a player's latest faction changes.
|
||||
*
|
||||
* \param pid The player ID whose faction changes should be used.
|
||||
* \param i The index of the faction.
|
||||
* \return The expulsion state.
|
||||
*/
|
||||
static bool GetFactionExpulsionState(unsigned short pid, unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the reputation at a certain index in a player's latest faction changes.
|
||||
*
|
||||
* \param pid The player ID whose faction changes should be used.
|
||||
* \param i The index of the faction.
|
||||
* \return The reputation.
|
||||
*/
|
||||
static int GetFactionReputation(unsigned short pid, unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the action type in a player's faction changes.
|
||||
*
|
||||
* \param pid The player ID whose faction changes should be used.
|
||||
* \param action The action (0 for RANK, 1 for EXPULSION, 2 for REPUTATION).
|
||||
* \return void
|
||||
*/
|
||||
static void SetFactionChangesAction(unsigned short pid, unsigned char action) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the factionId of the temporary faction stored on the server.
|
||||
*
|
||||
* \param factionId The factionId.
|
||||
* \return void
|
||||
*/
|
||||
static void SetFactionId(const char* factionId) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the rank of the temporary faction stored on the server.
|
||||
*
|
||||
* \param rank The rank.
|
||||
* \return void
|
||||
*/
|
||||
static void SetFactionRank(unsigned int rank) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the expulsion state of the temporary faction stored on the server.
|
||||
*
|
||||
* \param expulsionState The expulsion state.
|
||||
* \return void
|
||||
*/
|
||||
static void SetFactionExpulsionState(bool expulsionState) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the reputation of the temporary faction stored on the server.
|
||||
*
|
||||
* \param reputation The reputation.
|
||||
* \return void
|
||||
*/
|
||||
static void SetFactionReputation(int reputation) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Add the server's temporary faction to the faction changes for a player.
|
||||
*
|
||||
* In the process, the server's temporary faction will automatically be cleared so a new one
|
||||
* can be set up.
|
||||
*
|
||||
* \param pid The player ID whose faction changes should be used.
|
||||
* \return void
|
||||
*/
|
||||
static void AddFaction(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Send a PlayerFaction packet with a player's recorded faction changes.
|
||||
*
|
||||
* \param pid The player ID whose faction changes should be used.
|
||||
* \param toOthers Whether this packet should be sent only to other players or
|
||||
* only to the player it is about.
|
||||
* \return void
|
||||
*/
|
||||
static void SendFactionChanges(unsigned short pid, bool toOthers = false) noexcept;
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
#endif //OPENMW_FACTIONAPI_HPP
|
@ -1,86 +0,0 @@
|
||||
//
|
||||
// Created by koncord on 23.07.16.
|
||||
//
|
||||
|
||||
#include "GUI.hpp"
|
||||
#include <apps/openmw-mp/Script/ScriptFunctions.hpp>
|
||||
#include <apps/openmw-mp/Networking.hpp>
|
||||
#include <components/openmw-mp/NetworkMessages.hpp>
|
||||
|
||||
void GUIFunctions::_MessageBox(unsigned short pid, int id, const char *label) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
|
||||
player->guiMessageBox.id = id;
|
||||
player->guiMessageBox.label = label;
|
||||
player->guiMessageBox.type = Player::GUIMessageBox::MessageBox;
|
||||
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_GUI_MESSAGEBOX)->setPlayer(player);
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_GUI_MESSAGEBOX)->Send(false);
|
||||
}
|
||||
|
||||
void GUIFunctions::CustomMessageBox(unsigned short pid, int id, const char *label, const char *buttons) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
|
||||
player->guiMessageBox.id = id;
|
||||
player->guiMessageBox.label = label;
|
||||
player->guiMessageBox.buttons = buttons;
|
||||
player->guiMessageBox.type = Player::GUIMessageBox::CustomMessageBox;
|
||||
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_GUI_MESSAGEBOX)->setPlayer(player);
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_GUI_MESSAGEBOX)->Send(false);
|
||||
}
|
||||
|
||||
void GUIFunctions::InputDialog(unsigned short pid, int id, const char *label) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
|
||||
player->guiMessageBox.id = id;
|
||||
player->guiMessageBox.label = label;
|
||||
player->guiMessageBox.type = Player::GUIMessageBox::InputDialog;
|
||||
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_GUI_MESSAGEBOX)->setPlayer(player);
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_GUI_MESSAGEBOX)->Send(false);
|
||||
}
|
||||
|
||||
void GUIFunctions::PasswordDialog(unsigned short pid, int id, const char *label, const char *note) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
|
||||
player->guiMessageBox.id = id;
|
||||
player->guiMessageBox.label = label;
|
||||
player->guiMessageBox.note = note;
|
||||
player->guiMessageBox.type = Player::GUIMessageBox::PasswordDialog;
|
||||
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_GUI_MESSAGEBOX)->setPlayer(player);
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_GUI_MESSAGEBOX)->Send(false);
|
||||
}
|
||||
|
||||
void GUIFunctions::ListBox(unsigned short pid, int id, const char *label, const char *items)
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
|
||||
player->guiMessageBox.id = id;
|
||||
player->guiMessageBox.label = label;
|
||||
player->guiMessageBox.data = items;
|
||||
player->guiMessageBox.type = Player::GUIMessageBox::ListBox;
|
||||
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_GUI_MESSAGEBOX)->setPlayer(player);
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_GUI_MESSAGEBOX)->Send(false);
|
||||
}
|
||||
|
||||
void GUIFunctions::SetMapVisibility(unsigned short targetPID, unsigned short affectedPID, unsigned short state) noexcept
|
||||
{
|
||||
LOG_MESSAGE(Log::LOG_WARN, "stub");
|
||||
}
|
||||
|
||||
void GUIFunctions::SetMapVisibilityAll(unsigned short targetPID, unsigned short state) noexcept
|
||||
{
|
||||
LOG_MESSAGE(Log::LOG_WARN, "stub");
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
//
|
||||
// Created by koncord on 30.08.16.
|
||||
//
|
||||
|
||||
#ifndef OPENMW_GUIAPI_HPP
|
||||
#define OPENMW_GUIAPI_HPP
|
||||
|
||||
#define GUIAPI \
|
||||
{"MessageBox", GUIFunctions::_MessageBox},\
|
||||
{"CustomMessageBox", GUIFunctions::CustomMessageBox},\
|
||||
{"InputDialog", GUIFunctions::InputDialog},\
|
||||
{"PasswordDialog", GUIFunctions::PasswordDialog},\
|
||||
{"ListBox", GUIFunctions::ListBox},\
|
||||
{"SetMapVisibility", GUIFunctions::SetMapVisibility},\
|
||||
{"SetMapVisibilityAll", GUIFunctions::SetMapVisibilityAll}
|
||||
|
||||
class GUIFunctions
|
||||
{
|
||||
public:
|
||||
/* Do not rename into MessageBox to not conflict with WINAPI's MessageBox */
|
||||
static void _MessageBox(unsigned short pid, int id, const char *label) noexcept;
|
||||
|
||||
static void CustomMessageBox(unsigned short pid, int id, const char *label, const char *buttons) noexcept;
|
||||
static void InputDialog(unsigned short pid, int id, const char *label) noexcept;
|
||||
static void PasswordDialog(unsigned short pid, int id, const char *label, const char *note) noexcept;
|
||||
|
||||
static void ListBox(unsigned short pid, int id, const char *label, const char *items);
|
||||
|
||||
//state 0 - disallow, 1 - allow
|
||||
static void SetMapVisibility(unsigned short targetPID, unsigned short affectedPID, unsigned short state) noexcept;
|
||||
static void SetMapVisibilityAll(unsigned short targetPID, unsigned short state) noexcept;
|
||||
};
|
||||
|
||||
#endif //OPENMW_GUIAPI_HPP
|
@ -1,160 +0,0 @@
|
||||
//
|
||||
// Created by koncord on 02.03.16.
|
||||
//
|
||||
|
||||
#include "Items.hpp"
|
||||
#include <apps/openmw-mp/Script/ScriptFunctions.hpp>
|
||||
#include <components/openmw-mp/NetworkMessages.hpp>
|
||||
#include <apps/openmw-mp/Networking.hpp>
|
||||
#include <apps/openmw/mwworld/inventorystore.hpp>
|
||||
#include <components/misc/stringops.hpp>
|
||||
|
||||
using namespace mwmp;
|
||||
|
||||
void ItemFunctions::InitializeInventoryChanges(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
player->inventoryChanges.items.clear();
|
||||
player->inventoryChanges.action = InventoryChanges::SET;
|
||||
}
|
||||
|
||||
int ItemFunctions::GetEquipmentSize() noexcept
|
||||
{
|
||||
return MWWorld::InventoryStore::Slots;
|
||||
}
|
||||
|
||||
unsigned int ItemFunctions::GetInventoryChangesSize(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
return player->inventoryChanges.count;
|
||||
}
|
||||
|
||||
void ItemFunctions::EquipItem(unsigned short pid, unsigned short slot, const char *refId, unsigned int count, int charge) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
|
||||
player->equipedItems[slot].refId = refId;
|
||||
player->equipedItems[slot].count = count;
|
||||
player->equipedItems[slot].charge = charge;
|
||||
}
|
||||
|
||||
void ItemFunctions::UnequipItem(unsigned short pid, unsigned short slot) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
ItemFunctions::EquipItem(pid, slot, "", 0, -1);
|
||||
}
|
||||
|
||||
void ItemFunctions::AddItem(unsigned short pid, const char* refId, unsigned int count, int charge) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
Item item;
|
||||
item.refId = refId;
|
||||
item.count = count;
|
||||
item.charge = charge;
|
||||
|
||||
player->inventoryChanges.items.push_back(item);
|
||||
player->inventoryChanges.action = InventoryChanges::ADD;
|
||||
}
|
||||
|
||||
void ItemFunctions::RemoveItem(unsigned short pid, const char* refId, unsigned short count) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
Item item;
|
||||
item.refId = refId;
|
||||
item.count = count;
|
||||
|
||||
player->inventoryChanges.items.push_back(item);
|
||||
player->inventoryChanges.action = InventoryChanges::REMOVE;
|
||||
}
|
||||
|
||||
bool ItemFunctions::HasItemEquipped(unsigned short pid, const char* refId)
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, false);
|
||||
|
||||
for (int slot = 0; slot < MWWorld::InventoryStore::Slots; slot++)
|
||||
if (Misc::StringUtils::ciEqual(player->equipedItems[slot].refId, refId))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *ItemFunctions::GetEquipmentItemRefId(unsigned short pid, unsigned short slot) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
return player->equipedItems[slot].refId.c_str();
|
||||
}
|
||||
|
||||
int ItemFunctions::GetEquipmentItemCount(unsigned short pid, unsigned short slot) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
return player->equipedItems[slot].count;
|
||||
}
|
||||
|
||||
int ItemFunctions::GetEquipmentItemCharge(unsigned short pid, unsigned short slot) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
return player->equipedItems[slot].charge;
|
||||
}
|
||||
|
||||
const char *ItemFunctions::GetInventoryItemRefId(unsigned short pid, unsigned int i) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, "");
|
||||
|
||||
if (i >= player->inventoryChanges.count)
|
||||
return "invalid";
|
||||
|
||||
return player->inventoryChanges.items.at(i).refId.c_str();
|
||||
}
|
||||
|
||||
int ItemFunctions::GetInventoryItemCount(unsigned short pid, unsigned int i) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
return player->inventoryChanges.items.at(i).count;
|
||||
}
|
||||
|
||||
int ItemFunctions::GetInventoryItemCharge(unsigned short pid, unsigned int i) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
return player->inventoryChanges.items.at(i).charge;
|
||||
}
|
||||
|
||||
void ItemFunctions::SendEquipment(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_EQUIPMENT)->setPlayer(player);
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_EQUIPMENT)->Send(false);
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_EQUIPMENT)->Send(true);
|
||||
}
|
||||
|
||||
void ItemFunctions::SendInventoryChanges(unsigned short pid, bool toOthers) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_INVENTORY)->setPlayer(player);
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_INVENTORY)->Send(toOthers);
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
//
|
||||
// Created by koncord on 30.08.16.
|
||||
//
|
||||
|
||||
#ifndef OPENMW_ITEMAPI_HPP
|
||||
#define OPENMW_ITEMAPI_HPP
|
||||
|
||||
#define ITEMAPI \
|
||||
{"InitializeInventoryChanges", ItemFunctions::InitializeInventoryChanges},\
|
||||
\
|
||||
{"GetEquipmentSize", ItemFunctions::GetEquipmentSize},\
|
||||
{"GetInventoryChangesSize", ItemFunctions::GetInventoryChangesSize},\
|
||||
\
|
||||
{"EquipItem", ItemFunctions::EquipItem},\
|
||||
{"UnequipItem", ItemFunctions::UnequipItem},\
|
||||
\
|
||||
{"AddItem", ItemFunctions::AddItem},\
|
||||
{"RemoveItem", ItemFunctions::RemoveItem},\
|
||||
\
|
||||
{"HasItemEquipped", ItemFunctions::HasItemEquipped},\
|
||||
\
|
||||
{"GetEquipmentItemRefId", ItemFunctions::GetEquipmentItemRefId},\
|
||||
{"GetEquipmentItemCount", ItemFunctions::GetEquipmentItemCount},\
|
||||
{"GetEquipmentItemCharge", ItemFunctions::GetEquipmentItemCharge},\
|
||||
\
|
||||
{"GetInventoryItemRefId", ItemFunctions::GetInventoryItemRefId},\
|
||||
{"GetInventoryItemCount", ItemFunctions::GetInventoryItemCount},\
|
||||
{"GetInventoryItemCharge", ItemFunctions::GetInventoryItemCharge},\
|
||||
\
|
||||
{"SendEquipment", ItemFunctions::SendEquipment},\
|
||||
{"SendInventoryChanges", ItemFunctions::SendInventoryChanges}
|
||||
|
||||
class ItemFunctions
|
||||
{
|
||||
public:
|
||||
|
||||
static void InitializeInventoryChanges(unsigned short pid) noexcept;
|
||||
|
||||
static int GetEquipmentSize() noexcept;
|
||||
static unsigned int GetInventoryChangesSize(unsigned short pid) noexcept;
|
||||
|
||||
static void EquipItem(unsigned short pid, unsigned short slot, const char* refId, unsigned int count, int charge) noexcept;
|
||||
static void UnequipItem(unsigned short pid, unsigned short slot) noexcept;
|
||||
|
||||
static void AddItem(unsigned short pid, const char* refId, unsigned int count, int charge) noexcept;
|
||||
static void RemoveItem(unsigned short pid, const char* refId, unsigned short count) noexcept;
|
||||
|
||||
static bool HasItemEquipped(unsigned short pid, const char* refId);
|
||||
|
||||
static const char *GetEquipmentItemRefId(unsigned short pid, unsigned short slot) noexcept;
|
||||
static int GetEquipmentItemCount(unsigned short pid, unsigned short slot) noexcept;
|
||||
static int GetEquipmentItemCharge(unsigned short pid, unsigned short slot) noexcept;
|
||||
|
||||
static const char *GetInventoryItemRefId(unsigned short pid, unsigned int i) noexcept;
|
||||
static int GetInventoryItemCount(unsigned short pid, unsigned int i) noexcept;
|
||||
static int GetInventoryItemCharge(unsigned short pid, unsigned int i) noexcept;
|
||||
|
||||
static void SendEquipment(unsigned short pid) noexcept;
|
||||
static void SendInventoryChanges(unsigned short pid, bool toOthers = false) noexcept;
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
#endif //OPENMW_ITEMAPI_HPP
|
@ -1,62 +0,0 @@
|
||||
#include "Mechanics.hpp"
|
||||
#include <apps/openmw-mp/Script/ScriptFunctions.hpp>
|
||||
#include <components/openmw-mp/NetworkMessages.hpp>
|
||||
#include <apps/openmw-mp/Networking.hpp>
|
||||
#include <components/openmw-mp/Log.hpp>
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
bool MechanicsFunctions::IsWerewolf(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
return player->isWerewolf;
|
||||
}
|
||||
|
||||
void MechanicsFunctions::SetWerewolfState(unsigned short pid, bool isWerewolf)
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
player->isWerewolf = isWerewolf;
|
||||
}
|
||||
|
||||
void MechanicsFunctions::SendShapeshift(unsigned short pid)
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_SHAPESHIFT)->setPlayer(player);
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_SHAPESHIFT)->Send(false);
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_SHAPESHIFT)->Send(true);
|
||||
}
|
||||
|
||||
void MechanicsFunctions::Jail(unsigned short pid, int jailDays, bool ignoreJailTeleportation, bool ignoreJailSkillIncreases,
|
||||
const char* jailProgressText, const char* jailEndText) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
player->jailDays = jailDays;
|
||||
player->ignoreJailTeleportation = ignoreJailTeleportation;
|
||||
player->ignoreJailSkillIncreases = ignoreJailSkillIncreases;
|
||||
player->jailProgressText = jailProgressText;
|
||||
player->jailEndText = jailEndText;
|
||||
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_JAIL)->setPlayer(player);
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_JAIL)->Send(false);
|
||||
}
|
||||
|
||||
void MechanicsFunctions::Resurrect(unsigned short pid, unsigned int type) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
player->resurrectType = type;
|
||||
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_RESURRECT)->setPlayer(player);
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_RESURRECT)->Send(false);
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_RESURRECT)->Send(true);
|
||||
}
|
@ -1,89 +0,0 @@
|
||||
#ifndef OPENMW_MECHANICSAPI_HPP
|
||||
#define OPENMW_MECHANICSAPI_HPP
|
||||
|
||||
#include "../Types.hpp"
|
||||
|
||||
#define MECHANICSAPI \
|
||||
{"IsWerewolf", MechanicsFunctions::IsWerewolf},\
|
||||
\
|
||||
{"SetWerewolfState", MechanicsFunctions::SetWerewolfState},\
|
||||
\
|
||||
{"SendShapeshift", MechanicsFunctions::SendShapeshift},\
|
||||
\
|
||||
{"Jail", MechanicsFunctions::Jail},\
|
||||
{"Resurrect", MechanicsFunctions::Resurrect}
|
||||
|
||||
class MechanicsFunctions
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* \brief Check whether a player is a werewolf.
|
||||
*
|
||||
* This is based on the last PlayerShapeshift packet received or sent for that player.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \return The werewolf state.
|
||||
*/
|
||||
static bool IsWerewolf(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the werewolf state of a player.
|
||||
*
|
||||
* This changes the werewolf state recorded for that player in the server memory, but
|
||||
* does not by itself send a packet.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \param bool The new werewolf state.
|
||||
* \return void
|
||||
*/
|
||||
static void SetWerewolfState(unsigned short pid, bool isWerewolf);
|
||||
|
||||
/**
|
||||
* \brief Send a PlayerShapeshift packet about a player.
|
||||
*
|
||||
* This sends the packet to all players connected to the server. It is currently used
|
||||
* only to communicate werewolf states.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \return void
|
||||
*/
|
||||
static void SendShapeshift(unsigned short pid);
|
||||
|
||||
/**
|
||||
* \brief Send a PlayerJail packet about a player.
|
||||
*
|
||||
* This is similar to the player being jailed by a guard, but provides extra parameters for
|
||||
* increased flexibility.
|
||||
*
|
||||
* It is only sent to the player being jailed, as the other players will be informed of the
|
||||
* jailing's actual consequences via other packets sent by the affected client.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \param jailDays The number of days to spend jailed, where each day affects one skill point.
|
||||
* \param ignoreJailTeleportation Whether the player being teleported to the nearest jail
|
||||
* marker should be overridden.
|
||||
* \param ignoreJailSkillIncrease Whether the player's Sneak and Security skills should be
|
||||
* prevented from increasing as a result of the jailing,
|
||||
* overriding default behavior.
|
||||
* \param jailProgressText The text that should be displayed while jailed.
|
||||
* \param jailEndText The text that should be displayed once the jailing period is over.
|
||||
* \return void
|
||||
*/
|
||||
static void Jail(unsigned short pid, int jailDays, bool ignoreJailTeleportation = false, bool ignoreJailSkillIncreases = false,
|
||||
const char* jailProgressText = "", const char* jailEndText = "") noexcept;
|
||||
|
||||
/**
|
||||
* \brief Send a PlayerResurrect packet about a player.
|
||||
*
|
||||
* This sends the packet to all players connected to the server.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \param type The type of resurrection (0 for REGULAR, 1 for IMPERIAL_SHRINE,
|
||||
* 2 for TRIBUNAL_TEMPLE).
|
||||
* \return void
|
||||
*/
|
||||
static void Resurrect(unsigned short pid, unsigned int type) noexcept;
|
||||
};
|
||||
|
||||
#endif //OPENMW_MECHANICSAPI_HPP
|
@ -1,32 +0,0 @@
|
||||
#include "Miscellaneous.hpp"
|
||||
#include <apps/openmw-mp/Script/ScriptFunctions.hpp>
|
||||
#include <apps/openmw-mp/Networking.hpp>
|
||||
#include <components/openmw-mp/Log.hpp>
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
unsigned int MiscellaneousFunctions::GetLastPlayerId() noexcept
|
||||
{
|
||||
return Players::getLastPlayerId();
|
||||
}
|
||||
|
||||
int MiscellaneousFunctions::GetCurrentMpNum() noexcept
|
||||
{
|
||||
return mwmp::Networking::getPtr()->getCurrentMpNum();
|
||||
}
|
||||
|
||||
void MiscellaneousFunctions::SetCurrentMpNum(int mpNum) noexcept
|
||||
{
|
||||
mwmp::Networking::getPtr()->setCurrentMpNum(mpNum);
|
||||
}
|
||||
|
||||
void MiscellaneousFunctions::LogMessage(unsigned short level, const char *message) noexcept
|
||||
{
|
||||
LOG_MESSAGE_SIMPLE(level, "[Script]: %s", message);
|
||||
}
|
||||
|
||||
void MiscellaneousFunctions::LogAppend(unsigned short level, const char *message) noexcept
|
||||
{
|
||||
LOG_APPEND(level, "[Script]: %s", message);
|
||||
}
|
@ -1,79 +0,0 @@
|
||||
#ifndef OPENMW_MISCELLANEOUSAPI_HPP
|
||||
#define OPENMW_MISCELLANEOUSAPI_HPP
|
||||
|
||||
#include "../Types.hpp"
|
||||
|
||||
#define MISCELLANEOUSAPI \
|
||||
{"GetLastPlayerId", MiscellaneousFunctions::GetLastPlayerId},\
|
||||
\
|
||||
{"GetCurrentMpNum", MiscellaneousFunctions::GetCurrentMpNum},\
|
||||
{"SetCurrentMpNum", MiscellaneousFunctions::SetCurrentMpNum},\
|
||||
\
|
||||
{"LogMessage", MiscellaneousFunctions::LogMessage},\
|
||||
{"LogAppend", MiscellaneousFunctions::LogAppend}
|
||||
|
||||
class MiscellaneousFunctions
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* \brief Get the last player ID currently connected to the server.
|
||||
*
|
||||
* Every player receives a unique numerical index known as their player ID upon joining the
|
||||
* server.
|
||||
*
|
||||
* \return The player ID.
|
||||
*/
|
||||
static unsigned int GetLastPlayerId() noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the current (latest) mpNum generated by the server.
|
||||
*
|
||||
* Every object that did not exist in an .ESM or .ESP data file and has instead been placed or
|
||||
* spawned through a server-sent packet has a numerical index known as its mpNum.
|
||||
*
|
||||
* When ObjectPlace and ObjectSpawn packets are received from players, their objects lack mpNums,
|
||||
* so the server assigns them some based on incrementing the server's current mpNum, with the
|
||||
* operation's final mpNum becoming the server's new current mpNum.
|
||||
*
|
||||
* \return The mpNum.
|
||||
*/
|
||||
static int GetCurrentMpNum() noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the current (latest) mpNum generated by the server.
|
||||
*
|
||||
* When restarting a server, it is important to revert to the previous current (latest) mpNum
|
||||
* as stored in the server's data, so as to avoid starting over from 0 and ending up assigning
|
||||
* duplicate mpNums to objects.
|
||||
*
|
||||
* \param mpNum The number that should be used as the new current mpNum.
|
||||
* \return void
|
||||
*/
|
||||
static void SetCurrentMpNum(int mpNum) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Write a log message with its own timestamp.
|
||||
*
|
||||
* It will have "[Script]:" prepended to it so as to mark it as a script-generated log message.
|
||||
*
|
||||
* \param level The logging level used (0 for LOG_VERBOSE, 1 for LOG_INFO, 2 for LOG_WARN,
|
||||
* 3 for LOG_ERROR, 4 for LOG_FATAL).
|
||||
* \param message The message logged.
|
||||
* \return void
|
||||
*/
|
||||
static void LogMessage(unsigned short level, const char *message) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Write a log message without its own timestamp.
|
||||
*
|
||||
* It will have "[Script]:" prepended to it so as to mark it as a script-generated log message.
|
||||
*
|
||||
* \param level The logging level used (0 for LOG_VERBOSE, 1 for LOG_INFO, 2 for LOG_WARN,
|
||||
* 3 for LOG_ERROR, 4 for LOG_FATAL).
|
||||
* \param message The message logged.
|
||||
* \return void
|
||||
*/
|
||||
static void LogAppend(unsigned short level, const char *message) noexcept;
|
||||
};
|
||||
|
||||
#endif //OPENMW_MISCELLANEOUSAPI_HPP
|
@ -1,128 +0,0 @@
|
||||
#include "Positions.hpp"
|
||||
#include <apps/openmw-mp/Script/ScriptFunctions.hpp>
|
||||
#include <components/openmw-mp/NetworkMessages.hpp>
|
||||
#include <apps/openmw-mp/Player.hpp>
|
||||
#include <apps/openmw-mp/Networking.hpp>
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
void PositionFunctions::GetPos(unsigned short pid, float *x, float *y, float *z) noexcept
|
||||
{
|
||||
*x = 0.00;
|
||||
*y = 0.00;
|
||||
*z = 0.00;
|
||||
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
|
||||
*x = player->position.pos[0];
|
||||
*y = player->position.pos[1];
|
||||
*z = player->position.pos[2];
|
||||
}
|
||||
|
||||
double PositionFunctions::GetPosX(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0.0f);
|
||||
|
||||
return player->position.pos[0];
|
||||
}
|
||||
|
||||
double PositionFunctions::GetPosY(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0.0f);
|
||||
|
||||
return player->position.pos[1];
|
||||
}
|
||||
|
||||
double PositionFunctions::GetPosZ(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0.0f);
|
||||
|
||||
return player->position.pos[2];
|
||||
}
|
||||
|
||||
double PositionFunctions::GetPreviousCellPosX(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0.0f);
|
||||
|
||||
return player->previousCellPosition.pos[0];
|
||||
}
|
||||
|
||||
double PositionFunctions::GetPreviousCellPosY(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0.0f);
|
||||
|
||||
return player->previousCellPosition.pos[1];
|
||||
}
|
||||
|
||||
double PositionFunctions::GetPreviousCellPosZ(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0.0f);
|
||||
|
||||
return player->previousCellPosition.pos[2];
|
||||
}
|
||||
|
||||
void PositionFunctions::GetRot(unsigned short pid, float *x, float *y, float *z) noexcept
|
||||
{
|
||||
*x = 0.00;
|
||||
*y = 0.00;
|
||||
*z = 0.00;
|
||||
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
*x = player->position.rot[0];
|
||||
*y = player->position.rot[1];
|
||||
*z = player->position.rot[2];
|
||||
}
|
||||
|
||||
double PositionFunctions::GetRotX(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0.0f);
|
||||
|
||||
return player->position.rot[0];
|
||||
}
|
||||
|
||||
double PositionFunctions::GetRotZ(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0.0f);
|
||||
|
||||
return player->position.rot[2];
|
||||
}
|
||||
|
||||
void PositionFunctions::SetPos(unsigned short pid, double x, double y, double z) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
|
||||
player->position.pos[0] = x;
|
||||
player->position.pos[1] = y;
|
||||
player->position.pos[2] = z;
|
||||
}
|
||||
|
||||
void PositionFunctions::SetRot(unsigned short pid, double x, double z) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
player->position.rot[0] = x;
|
||||
player->position.rot[2] = z;
|
||||
}
|
||||
|
||||
void PositionFunctions::SendPos(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_POSITION)->setPlayer(player);
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_POSITION)->Send(false);
|
||||
}
|
@ -1,158 +0,0 @@
|
||||
#ifndef OPENMW_POSITIONAPI_HPP
|
||||
#define OPENMW_POSITIONAPI_HPP
|
||||
|
||||
#include "../Types.hpp"
|
||||
|
||||
#define POSITIONAPI \
|
||||
{"GetPos", PositionFunctions::GetPos},\
|
||||
{"GetPosX", PositionFunctions::GetPosX},\
|
||||
{"GetPosY", PositionFunctions::GetPosY},\
|
||||
{"GetPosZ", PositionFunctions::GetPosZ},\
|
||||
\
|
||||
{"GetPreviousCellPosX", PositionFunctions::GetPreviousCellPosX},\
|
||||
{"GetPreviousCellPosY", PositionFunctions::GetPreviousCellPosY},\
|
||||
{"GetPreviousCellPosZ", PositionFunctions::GetPreviousCellPosZ},\
|
||||
\
|
||||
{"GetRot", PositionFunctions::GetRot},\
|
||||
{"GetRotX", PositionFunctions::GetRotX},\
|
||||
{"GetRotZ", PositionFunctions::GetRotZ},\
|
||||
\
|
||||
{"SetPos", PositionFunctions::SetPos},\
|
||||
{"SetRot", PositionFunctions::SetRot},\
|
||||
\
|
||||
{"SendPos", PositionFunctions::SendPos}
|
||||
|
||||
|
||||
class PositionFunctions
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* \brief Assign the player's positional coordinate values to the variables passed as
|
||||
* parameters.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \param x The variable for the X position.
|
||||
* \param y The variable for the Y position.
|
||||
* \param z The variable for the Z position.
|
||||
* \return void
|
||||
*/
|
||||
static void GetPos(unsigned short pid, float *x, float *y, float *z) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the X position of a player.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \return The X position.
|
||||
*/
|
||||
static double GetPosX(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the Y position of a player.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \return The Y position.
|
||||
*/
|
||||
static double GetPosY(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the Z position of a player.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \return The Z position.
|
||||
*/
|
||||
static double GetPosZ(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the X position of a player from before their latest cell change.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \return The X position.
|
||||
*/
|
||||
static double GetPreviousCellPosX(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the Y position of a player from before their latest cell change.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \return The Y position.
|
||||
*/
|
||||
static double GetPreviousCellPosY(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the Z position of a player from before their latest cell change.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \return The Z position.
|
||||
*/
|
||||
static double GetPreviousCellPosZ(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Assign the player's rotational coordinate values to the variables passed as
|
||||
* parameters.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \param x The variable for the X rotation.
|
||||
* \param y The variable for the Y rotation.
|
||||
* \param z The variable for the Z rotation.
|
||||
* \return void
|
||||
*/
|
||||
static void GetRot(unsigned short pid, float *x, float *y, float *z) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the X rotation of a player.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \return The X rotation.
|
||||
*/
|
||||
static double GetRotX(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the Z rotation of a player.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \return The Z rotation.
|
||||
*/
|
||||
static double GetRotZ(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the position of a player.
|
||||
*
|
||||
* This changes the positional coordinates recorded for that player in the server memory, but
|
||||
* does not by itself send a packet.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \param x The X position.
|
||||
* \param y The Y position.
|
||||
* \param z The Z position.
|
||||
* \return void
|
||||
*/
|
||||
static void SetPos(unsigned short pid, double x, double y, double z) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the rotation of a player.
|
||||
*
|
||||
* This changes the rotational coordinates recorded for that player in the server memory, but
|
||||
* does not by itself send a packet.
|
||||
*
|
||||
* A player's Y rotation is always 0, which is why there is no Y rotation parameter.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \param x The X position.
|
||||
* \param z The Z position.
|
||||
* \return void
|
||||
*/
|
||||
static void SetRot(unsigned short pid, double x, double z) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Send a PlayerPosition packet about a player.
|
||||
*
|
||||
* It is only sent to the affected player.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \return void
|
||||
*/
|
||||
static void SendPos(unsigned short pid) noexcept;
|
||||
};
|
||||
|
||||
#endif //OPENMW_POSITIONAPI_HPP
|
@ -1,150 +0,0 @@
|
||||
#include "Quests.hpp"
|
||||
#include <apps/openmw-mp/Script/ScriptFunctions.hpp>
|
||||
#include <components/openmw-mp/NetworkMessages.hpp>
|
||||
#include <apps/openmw-mp/Networking.hpp>
|
||||
#include <components/misc/stringops.hpp>
|
||||
|
||||
using namespace mwmp;
|
||||
|
||||
void QuestFunctions::InitializeJournalChanges(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
player->journalChanges.journalItems.clear();
|
||||
}
|
||||
|
||||
void QuestFunctions::InitializeKillChanges(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
player->killChanges.kills.clear();
|
||||
}
|
||||
|
||||
unsigned int QuestFunctions::GetJournalChangesSize(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
return player->journalChanges.count;
|
||||
}
|
||||
|
||||
unsigned int QuestFunctions::GetKillChangesSize(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
return player->killChanges.count;
|
||||
}
|
||||
|
||||
void QuestFunctions::AddJournalEntry(unsigned short pid, const char* quest, unsigned int index, const char* actorRefId) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
mwmp::JournalItem journalItem;
|
||||
journalItem.type = JournalItem::ENTRY;
|
||||
journalItem.quest = quest;
|
||||
journalItem.index = index;
|
||||
journalItem.actorRefId = actorRefId;
|
||||
|
||||
player->journalChanges.journalItems.push_back(journalItem);
|
||||
}
|
||||
|
||||
void QuestFunctions::AddJournalIndex(unsigned short pid, const char* quest, unsigned int index) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
mwmp::JournalItem journalItem;
|
||||
journalItem.type = JournalItem::INDEX;
|
||||
journalItem.quest = quest;
|
||||
journalItem.index = index;
|
||||
|
||||
player->journalChanges.journalItems.push_back(journalItem);
|
||||
}
|
||||
|
||||
void QuestFunctions::AddKill(unsigned short pid, const char* refId, int number) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
mwmp::Kill kill;
|
||||
kill.refId = refId;
|
||||
kill.number = number;
|
||||
|
||||
player->killChanges.kills.push_back(kill);
|
||||
}
|
||||
|
||||
const char *QuestFunctions::GetJournalItemQuest(unsigned short pid, unsigned int i) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, "");
|
||||
|
||||
if (i >= player->journalChanges.count)
|
||||
return "invalid";
|
||||
|
||||
return player->journalChanges.journalItems.at(i).quest.c_str();
|
||||
}
|
||||
|
||||
int QuestFunctions::GetJournalItemIndex(unsigned short pid, unsigned int i) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
return player->journalChanges.journalItems.at(i).index;
|
||||
}
|
||||
|
||||
int QuestFunctions::GetJournalItemType(unsigned short pid, unsigned int i) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
return player->journalChanges.journalItems.at(i).type;
|
||||
}
|
||||
|
||||
const char *QuestFunctions::GetJournalItemActorRefId(unsigned short pid, unsigned int i) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
return player->journalChanges.journalItems.at(i).actorRefId.c_str();
|
||||
}
|
||||
|
||||
const char *QuestFunctions::GetKillRefId(unsigned short pid, unsigned int i) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, "");
|
||||
|
||||
if (i >= player->killChanges.count)
|
||||
return "invalid";
|
||||
|
||||
return player->killChanges.kills.at(i).refId.c_str();
|
||||
}
|
||||
|
||||
int QuestFunctions::GetKillNumber(unsigned short pid, unsigned int i) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
return player->killChanges.kills.at(i).number;
|
||||
}
|
||||
|
||||
void QuestFunctions::SendJournalChanges(unsigned short pid, bool toOthers) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_JOURNAL)->setPlayer(player);
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_JOURNAL)->Send(toOthers);
|
||||
}
|
||||
|
||||
void QuestFunctions::SendKillChanges(unsigned short pid, bool toOthers) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_KILL_COUNT)->setPlayer(player);
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_KILL_COUNT)->Send(toOthers);
|
||||
}
|
@ -1,176 +0,0 @@
|
||||
#ifndef OPENMW_QUESTAPI_HPP
|
||||
#define OPENMW_QUESTAPI_HPP
|
||||
|
||||
#define QUESTAPI \
|
||||
{"InitializeJournalChanges", QuestFunctions::InitializeJournalChanges},\
|
||||
{"InitializeKillChanges", QuestFunctions::InitializeKillChanges},\
|
||||
\
|
||||
{"GetJournalChangesSize", QuestFunctions::GetJournalChangesSize},\
|
||||
{"GetKillChangesSize", QuestFunctions::GetKillChangesSize},\
|
||||
\
|
||||
{"AddJournalEntry", QuestFunctions::AddJournalEntry},\
|
||||
{"AddJournalIndex", QuestFunctions::AddJournalIndex},\
|
||||
{"AddKill", QuestFunctions::AddKill},\
|
||||
\
|
||||
{"GetJournalItemQuest", QuestFunctions::GetJournalItemQuest},\
|
||||
{"GetJournalItemIndex", QuestFunctions::GetJournalItemIndex},\
|
||||
{"GetJournalItemType", QuestFunctions::GetJournalItemType},\
|
||||
{"GetJournalItemActorRefId", QuestFunctions::GetJournalItemActorRefId},\
|
||||
{"GetKillRefId", QuestFunctions::GetKillRefId},\
|
||||
{"GetKillNumber", QuestFunctions::GetKillNumber},\
|
||||
\
|
||||
{"SendJournalChanges", QuestFunctions::SendJournalChanges},\
|
||||
{"SendKillChanges", QuestFunctions::SendKillChanges}
|
||||
|
||||
class QuestFunctions
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* \brief Clear the last recorded journal changes for a player.
|
||||
*
|
||||
* This is used to initialize the sending of new PlayerJournal packets.
|
||||
*
|
||||
* \param pid The player ID whose journal changes should be used.
|
||||
* \return void
|
||||
*/
|
||||
static void InitializeJournalChanges(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Clear the last recorded kill count changes for a player.
|
||||
*
|
||||
* This is used to initialize the sending of new PlayerKillCount packets.
|
||||
*
|
||||
* \param pid The player ID whose kill count changes should be used.
|
||||
* \return void
|
||||
*/
|
||||
static void InitializeKillChanges(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the number of indexes in a player's latest journal changes.
|
||||
*
|
||||
* \param pid The player ID whose journal changes should be used.
|
||||
* \return The number of indexes.
|
||||
*/
|
||||
static unsigned int GetJournalChangesSize(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the number of indexes in a player's latest kill count changes.
|
||||
*
|
||||
* \param pid The player ID whose kill count changes should be used.
|
||||
* \return The number of indexes.
|
||||
*/
|
||||
static unsigned int GetKillChangesSize(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Add a new journal item of type ENTRY to the journal changes for a player.
|
||||
*
|
||||
* \param pid The player ID whose journal changes should be used.
|
||||
* \param quest The quest of the journal item.
|
||||
* \param index The quest index of the journal item.
|
||||
* \param actorRefId The actor refId of the journal item.
|
||||
* \return void
|
||||
*/
|
||||
static void AddJournalEntry(unsigned short pid, const char* quest, unsigned int index, const char* actorRefId) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Add a new journal item of type INDEX to the journal changes for a player.
|
||||
*
|
||||
* \param pid The player ID whose journal changes should be used.
|
||||
* \param quest The quest of the journal item.
|
||||
* \param index The quest index of the journal item.
|
||||
* \return void
|
||||
*/
|
||||
static void AddJournalIndex(unsigned short pid, const char* quest, unsigned int index) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Add a new kill count to the kill count changes for a player.
|
||||
*
|
||||
* \param pid The player ID whose kill count changes should be used.
|
||||
* \param refId The refId of the kill count.
|
||||
* \param number The number of kills in the kill count.
|
||||
* \return void
|
||||
*/
|
||||
static void AddKill(unsigned short pid, const char* refId, int number) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the quest at a certain index in a player's latest journal changes.
|
||||
*
|
||||
* \param pid The player ID whose journal changes should be used.
|
||||
* \param i The index of the journalItem.
|
||||
* \return The quest.
|
||||
*/
|
||||
static const char *GetJournalItemQuest(unsigned short pid, unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the quest index at a certain index in a player's latest journal changes.
|
||||
*
|
||||
* \param pid The player ID whose journal changes should be used.
|
||||
* \param i The index of the journalItem.
|
||||
* \return The quest index.
|
||||
*/
|
||||
static int GetJournalItemIndex(unsigned short pid, unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the journal item type at a certain index in a player's latest journal changes.
|
||||
*
|
||||
* \param pid The player ID whose journal changes should be used.
|
||||
* \param i The index of the journalItem.
|
||||
* \return The type (0 for ENTRY, 1 for INDEX).
|
||||
*/
|
||||
static int GetJournalItemType(unsigned short pid, unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the actor refId at a certain index in a player's latest journal changes.
|
||||
*
|
||||
* Every journal change has an associated actor, which is usually the quest giver.
|
||||
*
|
||||
* \param pid The player ID whose journal changes should be used.
|
||||
* \param i The index of the journalItem.
|
||||
* \return The actor refId.
|
||||
*/
|
||||
static const char *GetJournalItemActorRefId(unsigned short pid, unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the refId at a certain index in a player's latest kill count changes.
|
||||
*
|
||||
* \param pid The player ID whose kill count changes should be used.
|
||||
* \param i The index of the kill count.
|
||||
* \return The refId.
|
||||
*/
|
||||
static const char *GetKillRefId(unsigned short pid, unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the number of kills at a certain index in a player's latest kill count changes.
|
||||
*
|
||||
* \param pid The player ID whose kill count changes should be used.
|
||||
* \param i The index of the kill count.
|
||||
* \return The number of kills.
|
||||
*/
|
||||
static int GetKillNumber(unsigned short pid, unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Send a PlayerJournal packet with a player's recorded journal changes.
|
||||
*
|
||||
* \param pid The player ID whose journal changes should be used.
|
||||
* \param toOthers Whether this packet should be sent only to other players or
|
||||
* only to the player it is about.
|
||||
* \return void
|
||||
*/
|
||||
static void SendJournalChanges(unsigned short pid, bool toOthers = false) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Send a PlayerKillCount packet with a player's recorded kill count changes.
|
||||
*
|
||||
* \param pid The player ID whose kill count changes should be used.
|
||||
* \param toOthers Whether this packet should be sent only to other players or
|
||||
* only to the player it is about.
|
||||
* \return void
|
||||
*/
|
||||
static void SendKillChanges(unsigned short pid, bool toOthers = false) noexcept;
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
#endif //OPENMW_QUESTAPI_HPP
|
@ -1,33 +0,0 @@
|
||||
#include "Settings.hpp"
|
||||
#include <apps/openmw-mp/Script/ScriptFunctions.hpp>
|
||||
#include <components/openmw-mp/NetworkMessages.hpp>
|
||||
#include <apps/openmw-mp/Networking.hpp>
|
||||
#include <components/openmw-mp/Log.hpp>
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
void SettingFunctions::SetConsoleAllow(unsigned short pid, bool state)
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
|
||||
player->consoleAllowed = state;
|
||||
}
|
||||
|
||||
void SettingFunctions::SetDifficulty(unsigned short pid, int difficulty)
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
|
||||
player->difficulty = difficulty;
|
||||
}
|
||||
|
||||
void SettingFunctions::SendSettings(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_GAME_SETTINGS)->setPlayer(player);
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_GAME_SETTINGS)->Send(false);
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
#ifndef OPENMW_SETTINGSAPI_HPP
|
||||
#define OPENMW_SETTINGSAPI_HPP
|
||||
|
||||
#include "../Types.hpp"
|
||||
|
||||
#define SETTINGSAPI \
|
||||
{"SetConsoleAllow", SettingFunctions::SetConsoleAllow},\
|
||||
{"SetDifficulty", SettingFunctions::SetDifficulty},\
|
||||
\
|
||||
{"SendSettings", SettingFunctions::SendSettings}
|
||||
|
||||
class SettingFunctions
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* \brief Set whether the console is allowed for a player.
|
||||
*
|
||||
* This changes the console permission for that player in the server memory, but does not
|
||||
* by itself send a packet.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \param bool The console permission state.
|
||||
* \return void
|
||||
*/
|
||||
static void SetConsoleAllow(unsigned short pid, bool state);
|
||||
|
||||
/**
|
||||
* \brief Set the difficulty for a player.
|
||||
*
|
||||
* This changes the difficulty for that player in the server memory, but does not by itself
|
||||
* send a packet.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \param bool The difficulty.
|
||||
* \return void
|
||||
*/
|
||||
static void SetDifficulty(unsigned short pid, int difficulty);
|
||||
|
||||
/**
|
||||
* \brief Send a PlayerSettings packet to the player affected by it.
|
||||
*
|
||||
* \param pid The player ID to send it to.
|
||||
* \return void
|
||||
*/
|
||||
static void SendSettings(unsigned short pid) noexcept;
|
||||
};
|
||||
|
||||
#endif //OPENMW_SETTINGSAPI_HPP
|
@ -1,277 +0,0 @@
|
||||
#include "Spells.hpp"
|
||||
#include <apps/openmw-mp/Script/ScriptFunctions.hpp>
|
||||
#include <components/openmw-mp/NetworkMessages.hpp>
|
||||
#include <apps/openmw-mp/Networking.hpp>
|
||||
#include <components/misc/stringops.hpp>
|
||||
|
||||
using namespace mwmp;
|
||||
|
||||
void SpellFunctions::InitializeSpellbookChanges(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
player->spellbookChanges.spells.clear();
|
||||
}
|
||||
|
||||
unsigned int SpellFunctions::GetSpellbookChangesSize(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
return player->spellbookChanges.count;
|
||||
}
|
||||
|
||||
unsigned int SpellFunctions::GetSpellbookChangesAction(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
return player->spellbookChanges.action;
|
||||
}
|
||||
|
||||
void SpellFunctions::SetSpellbookChangesAction(unsigned short pid, unsigned char action) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
player->spellbookChanges.action = action;
|
||||
}
|
||||
|
||||
void SpellFunctions::AddSpell(unsigned short pid, const char* spellId) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
ESM::Spell spell;
|
||||
spell.mId = spellId;
|
||||
|
||||
player->spellbookChanges.spells.push_back(spell);
|
||||
}
|
||||
|
||||
void SpellFunctions::AddCustomSpell(unsigned short pid, const char* spellId, const char* spellName) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
ESM::Spell spell;
|
||||
spell.mName = spellName;
|
||||
spell.mId = spellId;
|
||||
|
||||
player->spellbookChanges.spells.push_back(spell);
|
||||
}
|
||||
|
||||
void SpellFunctions::AddCustomSpellData(unsigned short pid, const char* spellId, int type, int cost, int flags) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
int index = -1;
|
||||
for(int i = 0; i < player->spellbookChanges.spells.size(); i++)
|
||||
{
|
||||
if( strcmp(player->spellbookChanges.spells.at(i).mId.c_str(), spellId) == 0)
|
||||
{
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
|
||||
if(index == -1)
|
||||
return;
|
||||
|
||||
player->spellbookChanges.spells.at(index).mData.mType = type;
|
||||
player->spellbookChanges.spells.at(index).mData.mCost = cost;
|
||||
player->spellbookChanges.spells.at(index).mData.mFlags = flags;
|
||||
}
|
||||
|
||||
void SpellFunctions::AddCustomSpellEffect(unsigned short pid, const char* spellId, short effectId, signed char mSkill, signed char mAttribute, int mRange, int mArea, int mDuration, int mMagnMin, int mMagnMax) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
int index = -1;
|
||||
for(int i = 0; i < player->spellbookChanges.spells.size(); i++)
|
||||
{
|
||||
if( strcmp(player->spellbookChanges.spells.at(i).mId.c_str(), spellId) == 0)
|
||||
{
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
|
||||
if(index == -1)
|
||||
return;
|
||||
|
||||
ESM::ENAMstruct effect;
|
||||
effect.mEffectID = effectId;
|
||||
effect.mSkill = mSkill;
|
||||
effect.mAttribute = mAttribute;
|
||||
effect.mRange = mRange;
|
||||
effect.mArea = mArea;
|
||||
effect.mDuration = mDuration;
|
||||
effect.mMagnMin = mMagnMin;
|
||||
effect.mMagnMax = mMagnMax;
|
||||
|
||||
player->spellbookChanges.spells.at(index).mEffects.mList.push_back(effect);
|
||||
}
|
||||
|
||||
const char *SpellFunctions::GetSpellId(unsigned short pid, unsigned int i) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, "");
|
||||
|
||||
if (i >= player->spellbookChanges.count)
|
||||
return "invalid";
|
||||
|
||||
return player->spellbookChanges.spells.at(i).mId.c_str();
|
||||
}
|
||||
|
||||
const char *SpellFunctions::GetSpellName(unsigned short pid, unsigned int i) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, "");
|
||||
|
||||
if (i >= player->spellbookChanges.count)
|
||||
return "invalid";
|
||||
|
||||
return player->spellbookChanges.spells.at(i).mName.c_str();
|
||||
}
|
||||
|
||||
int SpellFunctions::GetSpellType(unsigned short pid, unsigned int i) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
if (i >= player->spellbookChanges.count)
|
||||
return 0;
|
||||
|
||||
return player->spellbookChanges.spells.at(i).mData.mType;
|
||||
}
|
||||
|
||||
int SpellFunctions::GetSpellCost(unsigned short pid, unsigned int i) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
if (i >= player->spellbookChanges.count)
|
||||
return 0;
|
||||
|
||||
return player->spellbookChanges.spells.at(i).mData.mCost;
|
||||
}
|
||||
|
||||
int SpellFunctions::GetSpellFlags(unsigned short pid, unsigned int i) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
if (i >= player->spellbookChanges.count)
|
||||
return 0;
|
||||
|
||||
return player->spellbookChanges.spells.at(i).mData.mFlags;
|
||||
}
|
||||
|
||||
unsigned int SpellFunctions::GetSpellEffectCount(unsigned short pid, unsigned int i) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
if (i >= player->spellbookChanges.count)
|
||||
return 0;
|
||||
|
||||
return player->spellbookChanges.spells.at(i).mEffects.mList.size();
|
||||
}
|
||||
|
||||
short SpellFunctions::GetSpellEffectId(unsigned short pid, unsigned int i, unsigned int j) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
if (i >= player->spellbookChanges.count)
|
||||
return 0;
|
||||
|
||||
return player->spellbookChanges.spells.at(i).mEffects.mList.at(j).mEffectID;
|
||||
}
|
||||
|
||||
signed char SpellFunctions::GetSpellEffectSkill(unsigned short pid, unsigned int i, unsigned int j) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
if (i >= player->spellbookChanges.count)
|
||||
return 0;
|
||||
|
||||
return player->spellbookChanges.spells.at(i).mEffects.mList.at(j).mSkill;
|
||||
}
|
||||
|
||||
signed char SpellFunctions::GetSpellEffectAttribute(unsigned short pid, unsigned int i, unsigned int j) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
if (i >= player->spellbookChanges.count)
|
||||
return 0;
|
||||
|
||||
return player->spellbookChanges.spells.at(i).mEffects.mList.at(j).mAttribute;
|
||||
}
|
||||
|
||||
int SpellFunctions::GetSpellEffectRange(unsigned short pid, unsigned int i, unsigned int j) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
if (i >= player->spellbookChanges.count)
|
||||
return 0;
|
||||
|
||||
return player->spellbookChanges.spells.at(i).mEffects.mList.at(j).mRange;
|
||||
}
|
||||
|
||||
int SpellFunctions::GetSpellEffectArea(unsigned short pid, unsigned int i, unsigned int j) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
if (i >= player->spellbookChanges.count)
|
||||
return 0;
|
||||
|
||||
return player->spellbookChanges.spells.at(i).mEffects.mList.at(j).mArea;
|
||||
}
|
||||
|
||||
int SpellFunctions::GetSpellEffectDuration(unsigned short pid, unsigned int i, unsigned int j) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
if (i >= player->spellbookChanges.count)
|
||||
return 0;
|
||||
|
||||
return player->spellbookChanges.spells.at(i).mEffects.mList.at(j).mDuration;
|
||||
}
|
||||
|
||||
int SpellFunctions::GetSpellEffectMagnMin(unsigned short pid, unsigned int i, unsigned int j) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
if (i >= player->spellbookChanges.count)
|
||||
return 0;
|
||||
|
||||
return player->spellbookChanges.spells.at(i).mEffects.mList.at(j).mMagnMin;
|
||||
}
|
||||
|
||||
int SpellFunctions::GetSpellEffectMagnMax(unsigned short pid, unsigned int i, unsigned int j) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
if (i >= player->spellbookChanges.count)
|
||||
return 0;
|
||||
|
||||
return player->spellbookChanges.spells.at(i).mEffects.mList.at(j).mMagnMax;
|
||||
}
|
||||
|
||||
void SpellFunctions::SendSpellbookChanges(unsigned short pid, bool toOthers) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_SPELLBOOK)->setPlayer(player);
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_SPELLBOOK)->Send(toOthers);
|
||||
}
|
@ -1,268 +0,0 @@
|
||||
#ifndef OPENMW_SPELLAPI_HPP
|
||||
#define OPENMW_SPELLAPI_HPP
|
||||
|
||||
#define SPELLAPI \
|
||||
{"InitializeSpellbookChanges", SpellFunctions::InitializeSpellbookChanges},\
|
||||
\
|
||||
{"GetSpellbookChangesSize", SpellFunctions::GetSpellbookChangesSize},\
|
||||
{"GetSpellbookChangesAction", SpellFunctions::GetSpellbookChangesAction},\
|
||||
\
|
||||
{"SetSpellbookChangesAction", SpellFunctions::SetSpellbookChangesAction},\
|
||||
{"AddSpell", SpellFunctions::AddSpell},\
|
||||
{"AddCustomSpell", SpellFunctions::AddCustomSpell},\
|
||||
{"AddCustomSpellData", SpellFunctions::AddCustomSpellData},\
|
||||
{"AddCustomSpellEffect", SpellFunctions::AddCustomSpellEffect},\
|
||||
\
|
||||
{"GetSpellId", SpellFunctions::GetSpellId},\
|
||||
{"GetSpellName", SpellFunctions::GetSpellName},\
|
||||
{"GetSpellType", SpellFunctions::GetSpellType},\
|
||||
{"GetSpellCost", SpellFunctions::GetSpellCost},\
|
||||
{"GetSpellFlags", SpellFunctions::GetSpellFlags},\
|
||||
{"GetSpellEffectCount", SpellFunctions::GetSpellEffectCount},\
|
||||
{"GetSpellEffectId", SpellFunctions::GetSpellEffectId},\
|
||||
{"GetSpellEffectSkill", SpellFunctions::GetSpellEffectSkill},\
|
||||
{"GetSpellEffectAttribute", SpellFunctions::GetSpellEffectAttribute},\
|
||||
{"GetSpellEffectRange", SpellFunctions::GetSpellEffectRange},\
|
||||
{"GetSpellEffectArea", SpellFunctions::GetSpellEffectArea},\
|
||||
{"GetSpellEffectDuration", SpellFunctions::GetSpellEffectDuration},\
|
||||
{"GetSpellEffectMagnMin", SpellFunctions::GetSpellEffectMagnMin},\
|
||||
{"GetSpellEffectMagnMax", SpellFunctions::GetSpellEffectMagnMax},\
|
||||
\
|
||||
{"SendSpellbookChanges", SpellFunctions::SendSpellbookChanges}
|
||||
|
||||
class SpellFunctions
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* \brief Clear the last recorded spellbook changes for a player.
|
||||
*
|
||||
* This is used to initialize the sending of new PlayerSpellbook packets.
|
||||
*
|
||||
* \param pid The player ID whose spellbook changes should be used.
|
||||
* \return void
|
||||
*/
|
||||
static void InitializeSpellbookChanges(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the number of indexes in a player's latest spellbook changes.
|
||||
*
|
||||
* \param pid The player ID whose spellbook changes should be used.
|
||||
* \return The number of indexes.
|
||||
*/
|
||||
static unsigned int GetSpellbookChangesSize(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the action type used in a player's latest spellbook changes.
|
||||
*
|
||||
* \param pid The player ID whose faction changes should be used.
|
||||
* \return The action type (0 for SET, 1 for ADD, 2 for REMOVE).
|
||||
*/
|
||||
static unsigned int GetSpellbookChangesAction(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the action type in a player's spellbook changes.
|
||||
*
|
||||
* \param pid The player ID whose spellbook changes should be used.
|
||||
* \param action The action (0 for SET, 1 for ADD, 2 for REMOVE).
|
||||
* \return void
|
||||
*/
|
||||
static void SetSpellbookChangesAction(unsigned short pid, unsigned char action) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Add a new spell to the spellbook changes for a player.
|
||||
*
|
||||
* \param pid The player ID whose spellbook changes should be used.
|
||||
* \param spellId The spellId of the spell.
|
||||
* \return void
|
||||
*/
|
||||
static void AddSpell(unsigned short pid, const char* spellId) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Add a new custom spell to the spellbook changes for a player.
|
||||
*
|
||||
* \param pid The player ID whose spellbook changes should be used.
|
||||
* \param spellId The spellId of the spell.
|
||||
* \param spellName The name of the spell.
|
||||
* \return void
|
||||
*/
|
||||
static void AddCustomSpell(unsigned short pid, const char* spellId, const char* spellName) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Add custom spell data to the spellbook changes for a player.
|
||||
*
|
||||
* \param pid The player ID whose spellbook changes should be used.
|
||||
* \param spellId The spellId of the spell.
|
||||
* \param type The type of the spell.
|
||||
* \param cost The cost of the spell.
|
||||
* \param flags The flags of the spell.
|
||||
* \return void
|
||||
*/
|
||||
static void AddCustomSpellData(unsigned short pid, const char* spellId, int type, int cost, int flags) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Add custom spell effect to the spellbook changes for a player.
|
||||
*
|
||||
* \param pid The player ID whose spellbook changes should be used.
|
||||
* \param spellId The spellId of the spell.
|
||||
* \param effectId The effectId of the spell effect.
|
||||
* \param mSkill The skill affected by the spell effect.
|
||||
* \param mAttribute The attribute affected by the spell effect.
|
||||
* \param mRange The range of the spell effect.
|
||||
* \param mArea The area of the spell effect.
|
||||
* \param mDuration The duration of the spell effect.
|
||||
* \param mMagnMin The minimum magnitude of the spell effect.
|
||||
* \param mMagnMax The maximum magnitude of the spell effect.
|
||||
* \return void
|
||||
*/
|
||||
static void AddCustomSpellEffect(unsigned short pid, const char* spellId, short effectId, signed char mSkill, signed char mAttribute, int mRange, int mArea, int mDuration, int mMagnMin, int mMagnMax) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the spellId at a certain index in a player's latest spellbook changes.
|
||||
*
|
||||
* \param pid The player ID whose spellbook changes should be used.
|
||||
* \param i The index of the spell.
|
||||
* \return The spellId.
|
||||
*/
|
||||
static const char *GetSpellId(unsigned short pid, unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the name of the spell at a certain index in a player's latest spellbook changes.
|
||||
*
|
||||
* \param pid The player ID whose spellbook changes should be used.
|
||||
* \param i The index of the spell.
|
||||
* \return The spell name.
|
||||
*/
|
||||
static const char *GetSpellName(unsigned short pid, unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the type of the spell at a certain index in a player's latest spellbook changes.
|
||||
*
|
||||
* \param pid The player ID whose spellbook changes should be used.
|
||||
* \param i The index of the spell.
|
||||
* \return The spell type.
|
||||
*/
|
||||
static int GetSpellType(unsigned short pid, unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the cost of the spell at a certain index in a player's latest spellbook changes.
|
||||
*
|
||||
* \param pid The player ID whose spellbook changes should be used.
|
||||
* \param i The index of the spell.
|
||||
* \return The spell cost.
|
||||
*/
|
||||
static int GetSpellCost(unsigned short pid, unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the flags of the spell at a certain index in a player's latest spellbook changes.
|
||||
*
|
||||
* \param pid The player ID whose spellbook changes should be used.
|
||||
* \param i The index of the spell.
|
||||
* \return The spell flags.
|
||||
*/
|
||||
static int GetSpellFlags(unsigned short pid, unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the number of effects on the spell at a certain index in a player's latest spellbook changes.
|
||||
*
|
||||
* \param pid The player ID whose spellbook changes should be used.
|
||||
* \param i The index of the spell.
|
||||
* \return The spell effect count.
|
||||
*/
|
||||
static unsigned int GetSpellEffectCount(unsigned short pid, unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the effectId of the effect at a certain index in the spell at another certain index in a player's latest spellbook changes.
|
||||
*
|
||||
* \param pid The player ID whose spellbook changes should be used.
|
||||
* \param i The index of the spell.
|
||||
* \param j The index of the effect.
|
||||
* \return The effectId.
|
||||
*/
|
||||
static short GetSpellEffectId(unsigned short pid, unsigned int i, unsigned int j) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the affected skill of the effect at a certain index in the spell at another certain index in a player's latest spellbook changes.
|
||||
*
|
||||
* \param pid The player ID whose spellbook changes should be used.
|
||||
* \param i The index of the spell.
|
||||
* \param j The index of the effect.
|
||||
* \return The affected skill.
|
||||
*/
|
||||
static signed char GetSpellEffectSkill(unsigned short pid, unsigned int i, unsigned int j) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the affected attribute of the effect at a certain index in the spell at another certain index in a player's latest spellbook changes.
|
||||
*
|
||||
* \param pid The player ID whose spellbook changes should be used.
|
||||
* \param i The index of the spell.
|
||||
* \param j The index of the effect.
|
||||
* \return The affected attribute.
|
||||
*/
|
||||
static signed char GetSpellEffectAttribute(unsigned short pid, unsigned int i, unsigned int j) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the range of the effect at a certain index in the spell at another certain index in a player's latest spellbook changes.
|
||||
*
|
||||
* \param pid The player ID whose spellbook changes should be used.
|
||||
* \param i The index of the spell.
|
||||
* \param j The index of the effect.
|
||||
* \return The range.
|
||||
*/
|
||||
static int GetSpellEffectRange(unsigned short pid, unsigned int i, unsigned int j) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the area of the effect at a certain index in the spell at another certain index in a player's latest spellbook changes.
|
||||
*
|
||||
* \param pid The player ID whose spellbook changes should be used.
|
||||
* \param i The index of the spell.
|
||||
* \param j The index of the effect.
|
||||
* \return The area.
|
||||
*/
|
||||
static int GetSpellEffectArea(unsigned short pid, unsigned int i, unsigned int j) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the duration of the effect at a certain index in the spell at another certain index in a player's latest spellbook changes.
|
||||
*
|
||||
* \param pid The player ID whose spellbook changes should be used.
|
||||
* \param i The index of the spell.
|
||||
* \param j The index of the effect.
|
||||
* \return The duration.
|
||||
*/
|
||||
static int GetSpellEffectDuration(unsigned short pid, unsigned int i, unsigned int j) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the minimum magnitude of the effect at a certain index in the spell at another certain index in a player's latest spellbook changes.
|
||||
*
|
||||
* \param pid The player ID whose spellbook changes should be used.
|
||||
* \param i The index of the spell.
|
||||
* \param j The index of the effect.
|
||||
* \return The minimum magnitude.
|
||||
*/
|
||||
static int GetSpellEffectMagnMin(unsigned short pid, unsigned int i, unsigned int j) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the maximum magnitude of the effect at a certain index in the spell at another certain index in a player's latest spellbook changes.
|
||||
*
|
||||
* \param pid The player ID whose spellbook changes should be used.
|
||||
* \param i The index of the spell.
|
||||
* \param j The index of the effect.
|
||||
* \return The maximum magnitude.
|
||||
*/
|
||||
static int GetSpellEffectMagnMax(unsigned short pid, unsigned int i, unsigned int j) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Send a PlayerSpellbook packet with a player's recorded spellbook changes.
|
||||
*
|
||||
* \param pid The player ID whose spellbook changes should be used.
|
||||
* \param toOthers Whether this packet should be sent only to other players or
|
||||
* only to the player it is about.
|
||||
* \return void
|
||||
*/
|
||||
static void SendSpellbookChanges(unsigned short pid, bool toOthers = false) noexcept;
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
#endif //OPENMW_SPELLAPI_HPP
|
@ -1,565 +0,0 @@
|
||||
//
|
||||
// Created by koncord on 29.02.16.
|
||||
//
|
||||
#include "Stats.hpp"
|
||||
|
||||
#include <apps/openmw-mp/Script/ScriptFunctions.hpp>
|
||||
#include <components/openmw-mp/NetworkMessages.hpp>
|
||||
#include <apps/openmw-mp/Networking.hpp>
|
||||
#include <components/esm/attr.hpp>
|
||||
#include <components/esm/loadskil.hpp>
|
||||
#include <components/misc/stringops.hpp>
|
||||
#include <components/openmw-mp/Log.hpp>
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
using namespace ESM;
|
||||
|
||||
int StatsFunctions::GetAttributeCount() noexcept
|
||||
{
|
||||
return Attribute::Length;
|
||||
}
|
||||
|
||||
int StatsFunctions::GetSkillCount() noexcept
|
||||
{
|
||||
return Skill::Length;
|
||||
}
|
||||
|
||||
int StatsFunctions::GetAttributeId(const char *name) noexcept
|
||||
{
|
||||
for (int x = 0; x < Attribute::Length; x++)
|
||||
{
|
||||
if (Misc::StringUtils::ciEqual(name, Attribute::sAttributeNames[x]))
|
||||
{
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int StatsFunctions::GetSkillId(const char *name) noexcept
|
||||
{
|
||||
for (int x = 0; x < Skill::Length; x++)
|
||||
{
|
||||
if (Misc::StringUtils::ciEqual(name, Skill::sSkillNames[x]))
|
||||
{
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
const char *StatsFunctions::GetAttributeName(unsigned short attribute) noexcept
|
||||
{
|
||||
if (attribute >= Attribute::Length)
|
||||
return "invalid";
|
||||
|
||||
return Attribute::sAttributeNames[attribute].c_str();
|
||||
}
|
||||
|
||||
const char *StatsFunctions::GetSkillName(unsigned short skill) noexcept
|
||||
{
|
||||
if (skill >= Skill::Length)
|
||||
return "invalid";
|
||||
|
||||
return Skill::sSkillNames[skill].c_str();
|
||||
}
|
||||
|
||||
const char *StatsFunctions::GetName(unsigned short pid) noexcept
|
||||
{
|
||||
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
return player->npc.mName.c_str();
|
||||
}
|
||||
|
||||
const char *StatsFunctions::GetRace(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
return player->npc.mRace.c_str();
|
||||
}
|
||||
|
||||
const char *StatsFunctions::GetHead(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
return player->npc.mHead.c_str();
|
||||
}
|
||||
|
||||
const char *StatsFunctions::GetHairstyle(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
return player->npc.mHair.c_str();
|
||||
}
|
||||
|
||||
int StatsFunctions::GetIsMale(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, false);
|
||||
|
||||
return player->npc.isMale();
|
||||
}
|
||||
|
||||
const char *StatsFunctions::GetBirthsign(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
return player->birthsign.c_str();
|
||||
}
|
||||
|
||||
const char *StatsFunctions::GetCreatureModel(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
return player->creatureModel.c_str();
|
||||
}
|
||||
|
||||
bool StatsFunctions::IsCreatureName(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
return player->useCreatureName;
|
||||
}
|
||||
|
||||
const char *StatsFunctions::GetDeathReason(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
return player->deathReason.c_str();
|
||||
}
|
||||
|
||||
int StatsFunctions::GetLevel(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
return player->creatureStats.mLevel;
|
||||
}
|
||||
|
||||
int StatsFunctions::GetLevelProgress(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
return player->npcStats.mLevelProgress;
|
||||
}
|
||||
|
||||
double StatsFunctions::GetHealthBase(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0.0f);
|
||||
|
||||
return player->creatureStats.mDynamic[0].mBase;
|
||||
}
|
||||
|
||||
double StatsFunctions::GetHealthCurrent(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0.0f);
|
||||
|
||||
return player->creatureStats.mDynamic[0].mCurrent;
|
||||
}
|
||||
|
||||
double StatsFunctions::GetMagickaBase(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0.0f);
|
||||
|
||||
return player->creatureStats.mDynamic[1].mBase;
|
||||
}
|
||||
|
||||
double StatsFunctions::GetMagickaCurrent(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0.0f);
|
||||
|
||||
return player->creatureStats.mDynamic[1].mCurrent;
|
||||
}
|
||||
|
||||
double StatsFunctions::GetFatigueBase(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0.0f);
|
||||
|
||||
return player->creatureStats.mDynamic[2].mBase;
|
||||
}
|
||||
|
||||
double StatsFunctions::GetFatigueCurrent(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0.0f);
|
||||
|
||||
return player->creatureStats.mDynamic[2].mCurrent;
|
||||
}
|
||||
|
||||
int StatsFunctions::GetAttributeBase(unsigned short pid, unsigned short attribute) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
if (attribute >= Attribute::Length)
|
||||
return 0;
|
||||
|
||||
return player->creatureStats.mAttributes[attribute].mBase;
|
||||
}
|
||||
|
||||
int StatsFunctions::GetAttributeCurrent(unsigned short pid, unsigned short attribute) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
if (attribute >= Attribute::Length)
|
||||
return 0;
|
||||
|
||||
return player->creatureStats.mAttributes[attribute].mCurrent;
|
||||
}
|
||||
|
||||
int StatsFunctions::GetSkillBase(unsigned short pid, unsigned short skill) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
if (skill >= Skill::Length)
|
||||
return 0;
|
||||
|
||||
return player->npcStats.mSkills[skill].mBase;
|
||||
}
|
||||
|
||||
int StatsFunctions::GetSkillCurrent(unsigned short pid, unsigned short skill) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
if (skill >= Skill::Length)
|
||||
return 0;
|
||||
|
||||
return player->npcStats.mSkills[skill].mCurrent;
|
||||
}
|
||||
|
||||
double StatsFunctions::GetSkillProgress(unsigned short pid, unsigned short skill) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0.0f);
|
||||
|
||||
if (skill >= Skill::Length)
|
||||
return 0;
|
||||
|
||||
return player->npcStats.mSkills[skill].mProgress;
|
||||
}
|
||||
|
||||
int StatsFunctions::GetSkillIncrease(unsigned short pid, unsigned int attribute) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
if (attribute > Attribute::Length)
|
||||
return 0;
|
||||
|
||||
return player->npcStats.mSkillIncrease[attribute];
|
||||
}
|
||||
|
||||
int StatsFunctions::GetBounty(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, 0);
|
||||
|
||||
return player->npcStats.mBounty;
|
||||
}
|
||||
|
||||
void StatsFunctions::SetName(unsigned short pid, const char *name) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
|
||||
if (player->npc.mName == name)
|
||||
return;
|
||||
|
||||
player->npc.mName = name;
|
||||
}
|
||||
|
||||
void StatsFunctions::SetRace(unsigned short pid, const char *race) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
|
||||
if (player->npc.mRace == race)
|
||||
return;
|
||||
|
||||
LOG_MESSAGE_SIMPLE(Log::LOG_VERBOSE, "Setting race for %s: %s -> %s", player->npc.mName.c_str(),
|
||||
player->npc.mRace.c_str(), race);
|
||||
|
||||
player->npc.mRace = race;
|
||||
}
|
||||
|
||||
void StatsFunctions::SetHead(unsigned short pid, const char *head) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
|
||||
if (player->npc.mHead == head)
|
||||
return;
|
||||
|
||||
player->npc.mHead = head;
|
||||
}
|
||||
|
||||
void StatsFunctions::SetHairstyle(unsigned short pid, const char *style) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
|
||||
if (player->npc.mHair == style)
|
||||
return;
|
||||
|
||||
player->npc.mHair = style;
|
||||
}
|
||||
|
||||
void StatsFunctions::SetIsMale(unsigned short pid, int value) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
|
||||
player->npc.setIsMale(value == true);
|
||||
}
|
||||
|
||||
void StatsFunctions::SetBirthsign(unsigned short pid, const char *sign) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
if (player->birthsign == sign)
|
||||
return;
|
||||
|
||||
player->birthsign = sign;
|
||||
}
|
||||
|
||||
void StatsFunctions::SetCreatureModel(unsigned short pid, const char *name, bool useCreatureName) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
player->creatureModel = name;
|
||||
player->useCreatureName = useCreatureName;
|
||||
|
||||
}
|
||||
|
||||
void StatsFunctions::SetLevel(unsigned short pid, int value) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
player->creatureStats.mLevel = value;
|
||||
}
|
||||
|
||||
void StatsFunctions::SetLevelProgress(unsigned short pid, int value) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
player->npcStats.mLevelProgress = value;
|
||||
}
|
||||
|
||||
void StatsFunctions::SetHealthBase(unsigned short pid, double value) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
|
||||
player->creatureStats.mDynamic[0].mBase = value;
|
||||
}
|
||||
|
||||
void StatsFunctions::SetHealthCurrent(unsigned short pid, double value) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
|
||||
player->creatureStats.mDynamic[0].mCurrent = value;
|
||||
}
|
||||
|
||||
void StatsFunctions::SetMagickaBase(unsigned short pid, double value) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
|
||||
player->creatureStats.mDynamic[1].mBase = value;
|
||||
}
|
||||
|
||||
void StatsFunctions::SetMagickaCurrent(unsigned short pid, double value) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
|
||||
player->creatureStats.mDynamic[1].mCurrent = value;
|
||||
}
|
||||
|
||||
void StatsFunctions::SetFatigueBase(unsigned short pid, double value) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
|
||||
player->creatureStats.mDynamic[2].mBase = value;
|
||||
}
|
||||
|
||||
void StatsFunctions::SetFatigueCurrent(unsigned short pid, double value) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
|
||||
player->creatureStats.mDynamic[2].mCurrent = value;
|
||||
}
|
||||
|
||||
void StatsFunctions::SetAttributeBase(unsigned short pid, unsigned short attribute, int value) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
|
||||
if (attribute >= Attribute::Length)
|
||||
return;
|
||||
|
||||
player->creatureStats.mAttributes[attribute].mBase = value;
|
||||
}
|
||||
|
||||
void StatsFunctions::SetAttributeCurrent(unsigned short pid, unsigned short attribute, int value) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
|
||||
if (attribute >= Attribute::Length)
|
||||
return;
|
||||
|
||||
player->creatureStats.mAttributes[attribute].mCurrent = value;
|
||||
}
|
||||
|
||||
void StatsFunctions::SetSkillBase(unsigned short pid, unsigned short skill, int value) noexcept //TODO: need packet for one value
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
|
||||
if (skill >= Skill::Length)
|
||||
return;
|
||||
|
||||
player->npcStats.mSkills[skill].mBase = value;
|
||||
}
|
||||
|
||||
void StatsFunctions::SetSkillCurrent(unsigned short pid, unsigned short skill, int value) noexcept //TODO: need packet for one value
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
|
||||
if (skill >= Skill::Length)
|
||||
return;
|
||||
|
||||
player->npcStats.mSkills[skill].mCurrent = value;
|
||||
}
|
||||
|
||||
void StatsFunctions::SetSkillProgress(unsigned short pid, unsigned short skill, double value) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
if (skill >= Skill::Length)
|
||||
return;
|
||||
|
||||
player->npcStats.mSkills[skill].mProgress = value;
|
||||
}
|
||||
|
||||
void StatsFunctions::SetSkillIncrease(unsigned short pid, unsigned int attribute, int value) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
|
||||
if (attribute > Attribute::Length)
|
||||
return;
|
||||
|
||||
player->npcStats.mSkillIncrease[attribute] = value;
|
||||
}
|
||||
|
||||
void StatsFunctions::SetBounty(unsigned short pid, int value) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
player->npcStats.mBounty = value;
|
||||
}
|
||||
|
||||
void StatsFunctions::SetCharGenStage(unsigned short pid, int start, int end) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
|
||||
player->charGenStage.current = start;
|
||||
player->charGenStage.end = end;
|
||||
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_CHARGEN)->setPlayer(player);
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_CHARGEN)->Send(false);
|
||||
}
|
||||
|
||||
void StatsFunctions::SendBaseInfo(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_BASEINFO)->setPlayer(player);
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_BASEINFO)->Send(false);
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_BASEINFO)->Send(true);
|
||||
}
|
||||
|
||||
void StatsFunctions::SendStatsDynamic(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_STATS_DYNAMIC)->setPlayer(player);
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_STATS_DYNAMIC)->Send(false);
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_STATS_DYNAMIC)->Send(true);
|
||||
}
|
||||
|
||||
void StatsFunctions::SendAttributes(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_ATTRIBUTE)->setPlayer(player);
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_ATTRIBUTE)->Send(false);
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_ATTRIBUTE)->Send(true);
|
||||
}
|
||||
|
||||
void StatsFunctions::SendSkills(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_SKILL)->setPlayer(player);
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_SKILL)->Send(false);
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_SKILL)->Send(true);
|
||||
}
|
||||
|
||||
void StatsFunctions::SendLevel(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_LEVEL)->setPlayer(player);
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_LEVEL)->Send(false);
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_LEVEL)->Send(true);
|
||||
}
|
||||
|
||||
void StatsFunctions::SendBounty(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_BOUNTY)->setPlayer(player);
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_BOUNTY)->Send(false);
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_PLAYER_BOUNTY)->Send(true);
|
||||
}
|
@ -1,163 +0,0 @@
|
||||
//
|
||||
// Created by koncord on 30.08.16.
|
||||
//
|
||||
|
||||
#ifndef OPENMW_STATAPI_HPP
|
||||
#define OPENMW_STATAPI_HPP
|
||||
|
||||
#define STATAPI \
|
||||
{"GetAttributeCount", StatsFunctions::GetAttributeCount},\
|
||||
{"GetSkillCount", StatsFunctions::GetSkillCount},\
|
||||
{"GetAttributeId", StatsFunctions::GetAttributeId},\
|
||||
{"GetSkillId", StatsFunctions::GetSkillId},\
|
||||
{"GetAttributeName", StatsFunctions::GetAttributeName},\
|
||||
{"GetSkillName", StatsFunctions::GetSkillName},\
|
||||
\
|
||||
{"GetName", StatsFunctions::GetName},\
|
||||
{"GetRace", StatsFunctions::GetRace},\
|
||||
{"GetHead", StatsFunctions::GetHead},\
|
||||
{"GetHair", StatsFunctions::GetHairstyle},\
|
||||
{"GetIsMale", StatsFunctions::GetIsMale},\
|
||||
{"GetBirthsign", StatsFunctions::GetBirthsign},\
|
||||
{"GetCreatureModel", StatsFunctions::GetCreatureModel},\
|
||||
{"IsCreatureName", StatsFunctions::IsCreatureName},\
|
||||
{"GetDeathReason", StatsFunctions::GetDeathReason},\
|
||||
\
|
||||
{"GetLevel", StatsFunctions::GetLevel},\
|
||||
{"GetLevelProgress", StatsFunctions::GetLevelProgress},\
|
||||
\
|
||||
{"GetHealthBase", StatsFunctions::GetHealthBase},\
|
||||
{"GetHealthCurrent", StatsFunctions::GetHealthCurrent},\
|
||||
\
|
||||
{"GetMagickaBase", StatsFunctions::GetMagickaBase},\
|
||||
{"GetMagickaCurrent", StatsFunctions::GetMagickaCurrent},\
|
||||
\
|
||||
{"GetFatigueBase", StatsFunctions::GetFatigueBase},\
|
||||
{"GetFatigueCurrent", StatsFunctions::GetFatigueCurrent},\
|
||||
\
|
||||
{"GetAttributeBase", StatsFunctions::GetAttributeBase},\
|
||||
{"GetAttributeCurrent", StatsFunctions::GetAttributeCurrent},\
|
||||
\
|
||||
{"GetSkillBase", StatsFunctions::GetSkillBase},\
|
||||
{"GetSkillCurrent", StatsFunctions::GetSkillCurrent},\
|
||||
{"GetSkillProgress", StatsFunctions::GetSkillProgress},\
|
||||
{"GetSkillIncrease", StatsFunctions::GetSkillIncrease},\
|
||||
\
|
||||
{"GetBounty", StatsFunctions::GetBounty},\
|
||||
\
|
||||
{"SetName", StatsFunctions::SetName},\
|
||||
{"SetRace", StatsFunctions::SetRace},\
|
||||
{"SetHead", StatsFunctions::SetHead},\
|
||||
{"SetHair", StatsFunctions::SetHairstyle},\
|
||||
{"SetIsMale", StatsFunctions::SetIsMale},\
|
||||
{"SetBirthsign", StatsFunctions::SetBirthsign},\
|
||||
{"SetCreatureModel", StatsFunctions::SetCreatureModel},\
|
||||
\
|
||||
{"SetLevel", StatsFunctions::SetLevel},\
|
||||
{"SetLevelProgress", StatsFunctions::SetLevelProgress},\
|
||||
\
|
||||
{"SetHealthBase", StatsFunctions::SetHealthBase},\
|
||||
{"SetHealthCurrent", StatsFunctions::SetHealthCurrent},\
|
||||
{"SetMagickaBase", StatsFunctions::SetMagickaBase},\
|
||||
{"SetMagickaCurrent", StatsFunctions::SetMagickaCurrent},\
|
||||
{"SetFatigueBase", StatsFunctions::SetFatigueBase},\
|
||||
{"SetFatigueCurrent", StatsFunctions::SetFatigueCurrent},\
|
||||
\
|
||||
{"SetAttributeBase", StatsFunctions::SetAttributeBase},\
|
||||
{"SetAttributeCurrent", StatsFunctions::SetAttributeCurrent},\
|
||||
\
|
||||
{"SetSkillBase", StatsFunctions::SetSkillBase},\
|
||||
{"SetSkillCurrent", StatsFunctions::SetSkillCurrent},\
|
||||
{"SetSkillProgress", StatsFunctions::SetSkillProgress},\
|
||||
{"SetSkillIncrease", StatsFunctions::SetSkillIncrease},\
|
||||
\
|
||||
{"SetBounty", StatsFunctions::SetBounty},\
|
||||
{"SetCharGenStage", StatsFunctions::SetCharGenStage},\
|
||||
\
|
||||
{"SendBaseInfo", StatsFunctions::SendBaseInfo},\
|
||||
\
|
||||
{"SendStatsDynamic", StatsFunctions::SendStatsDynamic},\
|
||||
{"SendAttributes", StatsFunctions::SendAttributes},\
|
||||
{"SendSkills", StatsFunctions::SendSkills},\
|
||||
{"SendLevel", StatsFunctions::SendLevel},\
|
||||
{"SendBounty", StatsFunctions::SendBounty}
|
||||
|
||||
class StatsFunctions
|
||||
{
|
||||
public:
|
||||
static int GetAttributeCount() noexcept;
|
||||
static int GetSkillCount() noexcept;
|
||||
static int GetAttributeId(const char *name) noexcept;
|
||||
static int GetSkillId(const char *name) noexcept;
|
||||
static const char *GetAttributeName(unsigned short attribute) noexcept;
|
||||
static const char *GetSkillName(unsigned short skill) noexcept;
|
||||
|
||||
static const char *GetName(unsigned short pid) noexcept;
|
||||
static const char *GetRace(unsigned short pid) noexcept;
|
||||
static const char *GetHead(unsigned short pid) noexcept;
|
||||
static const char *GetHairstyle(unsigned short pid) noexcept;
|
||||
static int GetIsMale(unsigned short pid) noexcept;
|
||||
static const char *GetBirthsign(unsigned short pid) noexcept;
|
||||
static const char *GetCreatureModel(unsigned short pid) noexcept;
|
||||
static bool IsCreatureName(unsigned short pid) noexcept;
|
||||
static const char *GetDeathReason(unsigned short pid) noexcept;
|
||||
|
||||
static int GetLevel(unsigned short pid) noexcept;
|
||||
static int GetLevelProgress(unsigned short pid) noexcept;
|
||||
|
||||
static double GetHealthBase(unsigned short pid) noexcept;
|
||||
static double GetHealthCurrent(unsigned short pid) noexcept;
|
||||
static double GetMagickaBase(unsigned short pid) noexcept;
|
||||
static double GetMagickaCurrent(unsigned short pid) noexcept;
|
||||
static double GetFatigueBase(unsigned short pid) noexcept;
|
||||
static double GetFatigueCurrent(unsigned short pid) noexcept;
|
||||
|
||||
static int GetAttributeBase(unsigned short pid, unsigned short attribute) noexcept;
|
||||
static int GetAttributeCurrent(unsigned short pid, unsigned short attribute) noexcept;
|
||||
|
||||
static int GetSkillBase(unsigned short pid, unsigned short skill) noexcept;
|
||||
static int GetSkillCurrent(unsigned short pid, unsigned short skill) noexcept;
|
||||
static double GetSkillProgress(unsigned short pid, unsigned short skill) noexcept;
|
||||
static int GetSkillIncrease(unsigned short pid, unsigned int pos) noexcept;
|
||||
|
||||
static int GetBounty(unsigned short pid) noexcept;
|
||||
|
||||
static void SetName(unsigned short pid, const char *name) noexcept;
|
||||
static void SetRace(unsigned short pid, const char *race) noexcept;
|
||||
static void SetHead(unsigned short pid, const char *head) noexcept;
|
||||
static void SetHairstyle(unsigned short pid, const char *style) noexcept;
|
||||
static void SetIsMale(unsigned short pid, int male) noexcept;
|
||||
static void SetBirthsign(unsigned short pid, const char *name) noexcept;
|
||||
static void SetCreatureModel(unsigned short pid, const char *name, bool useCreatureName) noexcept;
|
||||
|
||||
static void SetLevel(unsigned short pid, int value) noexcept;
|
||||
static void SetLevelProgress(unsigned short pid, int value) noexcept;
|
||||
|
||||
static void SetHealthBase(unsigned short pid, double value) noexcept;
|
||||
static void SetHealthCurrent(unsigned short pid, double value) noexcept;
|
||||
static void SetMagickaBase(unsigned short pid, double value) noexcept;
|
||||
static void SetMagickaCurrent(unsigned short pid, double value) noexcept;
|
||||
static void SetFatigueBase(unsigned short pid, double value) noexcept;
|
||||
static void SetFatigueCurrent(unsigned short pid, double value) noexcept;
|
||||
|
||||
static void SetAttributeBase(unsigned short pid, unsigned short attribute, int value) noexcept;
|
||||
static void SetAttributeCurrent(unsigned short pid, unsigned short attribute, int value) noexcept;
|
||||
|
||||
static void SetSkillBase(unsigned short pid, unsigned short skill, int value) noexcept;
|
||||
static void SetSkillCurrent(unsigned short pid, unsigned short skill, int value) noexcept;
|
||||
static void SetSkillProgress(unsigned short pid, unsigned short skill, double value) noexcept;
|
||||
static void SetSkillIncrease(unsigned short pid, unsigned int pos, int value) noexcept;
|
||||
|
||||
static void SetBounty(unsigned short pid, int value) noexcept;
|
||||
static void SetCharGenStage(unsigned short pid, int start, int end) noexcept;
|
||||
|
||||
static void SendBaseInfo(unsigned short pid) noexcept;
|
||||
|
||||
static void SendStatsDynamic(unsigned short pid) noexcept;
|
||||
static void SendAttributes(unsigned short pid) noexcept;
|
||||
static void SendSkills(unsigned short pid) noexcept;
|
||||
static void SendLevel(unsigned short pid) noexcept;
|
||||
static void SendBounty(unsigned short pid) noexcept;
|
||||
};
|
||||
|
||||
#endif //OPENMW_STATAPI_HPP
|
@ -1,58 +0,0 @@
|
||||
//
|
||||
// Created by koncord on 15.03.16.
|
||||
//
|
||||
|
||||
#include <apps/openmw-mp/Script/ScriptFunctions.hpp>
|
||||
#include <components/openmw-mp/NetworkMessages.hpp>
|
||||
#include <Player.hpp>
|
||||
#include <Networking.hpp>
|
||||
#include <Script/API/TimerAPI.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace mwmp;
|
||||
|
||||
int ScriptFunctions::CreateTimer(ScriptFunc callback, int msec) noexcept
|
||||
{
|
||||
return mwmp::TimerAPI::CreateTimer(callback, msec, "", vector<boost::any>());
|
||||
}
|
||||
|
||||
int ScriptFunctions::CreateTimerEx(ScriptFunc callback, int msec, const char *types, va_list args) noexcept
|
||||
{
|
||||
try
|
||||
{
|
||||
vector<boost::any> params;
|
||||
GetArguments(params, args, types);
|
||||
|
||||
return mwmp::TimerAPI::CreateTimer(callback, msec, types, params);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ScriptFunctions::StartTimer(int timerId) noexcept
|
||||
{
|
||||
TimerAPI::StartTimer(timerId);
|
||||
}
|
||||
|
||||
void ScriptFunctions::StopTimer(int timerId) noexcept
|
||||
{
|
||||
TimerAPI::StopTimer(timerId);
|
||||
}
|
||||
|
||||
void ScriptFunctions::RestartTimer(int timerId, int msec) noexcept
|
||||
{
|
||||
TimerAPI::ResetTimer(timerId, msec);
|
||||
}
|
||||
|
||||
void ScriptFunctions::FreeTimer(int timerId) noexcept
|
||||
{
|
||||
TimerAPI::FreeTimer(timerId);
|
||||
}
|
||||
|
||||
bool ScriptFunctions::IsTimerElapsed(int timerId) noexcept
|
||||
{
|
||||
return TimerAPI::IsEndTimer(timerId);
|
||||
}
|
@ -1,361 +0,0 @@
|
||||
#include <components/openmw-mp/NetworkMessages.hpp>
|
||||
#include <components/openmw-mp/Base/BaseEvent.hpp>
|
||||
|
||||
#include <apps/openmw-mp/Networking.hpp>
|
||||
#include <apps/openmw-mp/Player.hpp>
|
||||
#include <apps/openmw-mp/Utils.hpp>
|
||||
#include <apps/openmw-mp/Script/ScriptFunctions.hpp>
|
||||
|
||||
#include "World.hpp"
|
||||
|
||||
using namespace mwmp;
|
||||
|
||||
BaseEvent *readEvent;
|
||||
BaseEvent writeEvent;
|
||||
|
||||
WorldObject tempWorldObject;
|
||||
const WorldObject emptyWorldObject = {};
|
||||
|
||||
ContainerItem tempContainerItem;
|
||||
const ContainerItem emptyContainerItem = {};
|
||||
|
||||
void WorldFunctions::ReadLastEvent() noexcept
|
||||
{
|
||||
readEvent = mwmp::Networking::getPtr()->getLastEvent();
|
||||
}
|
||||
|
||||
void WorldFunctions::InitializeEvent(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, );
|
||||
|
||||
writeEvent.cell.blank();
|
||||
writeEvent.worldObjects.clear();
|
||||
writeEvent.guid = player->guid;
|
||||
}
|
||||
|
||||
unsigned int WorldFunctions::GetObjectChangesSize() noexcept
|
||||
{
|
||||
return readEvent->worldObjectCount;
|
||||
}
|
||||
|
||||
unsigned char WorldFunctions::GetEventAction() noexcept
|
||||
{
|
||||
return readEvent->action;
|
||||
}
|
||||
|
||||
const char *WorldFunctions::GetObjectRefId(unsigned int i) noexcept
|
||||
{
|
||||
return readEvent->worldObjects.at(i).refId.c_str();
|
||||
}
|
||||
|
||||
int WorldFunctions::GetObjectRefNumIndex(unsigned int i) noexcept
|
||||
{
|
||||
return readEvent->worldObjects.at(i).refNumIndex;
|
||||
}
|
||||
|
||||
int WorldFunctions::GetObjectMpNum(unsigned int i) noexcept
|
||||
{
|
||||
return readEvent->worldObjects.at(i).mpNum;
|
||||
}
|
||||
|
||||
int WorldFunctions::GetObjectCount(unsigned int i) noexcept
|
||||
{
|
||||
return readEvent->worldObjects.at(i).count;
|
||||
}
|
||||
|
||||
int WorldFunctions::GetObjectCharge(unsigned int i) noexcept
|
||||
{
|
||||
return readEvent->worldObjects.at(i).charge;
|
||||
}
|
||||
|
||||
int WorldFunctions::GetObjectGoldValue(unsigned int i) noexcept
|
||||
{
|
||||
return readEvent->worldObjects.at(i).goldValue;
|
||||
}
|
||||
|
||||
double WorldFunctions::GetObjectScale(unsigned int i) noexcept
|
||||
{
|
||||
return readEvent->worldObjects.at(i).scale;
|
||||
}
|
||||
|
||||
bool WorldFunctions::GetObjectState(unsigned int i) noexcept
|
||||
{
|
||||
return readEvent->worldObjects.at(i).objectState;
|
||||
}
|
||||
|
||||
int WorldFunctions::GetObjectDoorState(unsigned int i) noexcept
|
||||
{
|
||||
return readEvent->worldObjects.at(i).doorState;
|
||||
}
|
||||
|
||||
int WorldFunctions::GetObjectLockLevel(unsigned int i) noexcept
|
||||
{
|
||||
return readEvent->worldObjects.at(i).lockLevel;
|
||||
}
|
||||
|
||||
double WorldFunctions::GetObjectPosX(unsigned int i) noexcept
|
||||
{
|
||||
return readEvent->worldObjects.at(i).position.pos[0];
|
||||
}
|
||||
|
||||
double WorldFunctions::GetObjectPosY(unsigned int i) noexcept
|
||||
{
|
||||
return readEvent->worldObjects.at(i).position.pos[1];
|
||||
}
|
||||
|
||||
double WorldFunctions::GetObjectPosZ(unsigned int i) noexcept
|
||||
{
|
||||
return readEvent->worldObjects.at(i).position.pos[2];
|
||||
}
|
||||
|
||||
double WorldFunctions::GetObjectRotX(unsigned int i) noexcept
|
||||
{
|
||||
return readEvent->worldObjects.at(i).position.rot[0];
|
||||
}
|
||||
|
||||
double WorldFunctions::GetObjectRotY(unsigned int i) noexcept
|
||||
{
|
||||
return readEvent->worldObjects.at(i).position.rot[1];
|
||||
}
|
||||
|
||||
double WorldFunctions::GetObjectRotZ(unsigned int i) noexcept
|
||||
{
|
||||
return readEvent->worldObjects.at(i).position.rot[2];
|
||||
}
|
||||
|
||||
unsigned int WorldFunctions::GetContainerChangesSize(unsigned int objectIndex) noexcept
|
||||
{
|
||||
return readEvent->worldObjects.at(objectIndex).containerItemCount;
|
||||
}
|
||||
|
||||
const char *WorldFunctions::GetContainerItemRefId(unsigned int objectIndex, unsigned int itemIndex) noexcept
|
||||
{
|
||||
return readEvent->worldObjects.at(objectIndex)
|
||||
.containerItems.at(itemIndex).refId.c_str();
|
||||
}
|
||||
|
||||
int WorldFunctions::GetContainerItemCount(unsigned int objectIndex, unsigned int itemIndex) noexcept
|
||||
{
|
||||
return readEvent->worldObjects.at(objectIndex)
|
||||
.containerItems.at(itemIndex).count;
|
||||
}
|
||||
|
||||
int WorldFunctions::GetContainerItemCharge(unsigned int objectIndex, unsigned int itemIndex) noexcept
|
||||
{
|
||||
return readEvent->worldObjects.at(objectIndex)
|
||||
.containerItems.at(itemIndex).charge;
|
||||
}
|
||||
|
||||
int WorldFunctions::GetContainerItemActionCount(unsigned int objectIndex, unsigned int itemIndex) noexcept
|
||||
{
|
||||
return readEvent->worldObjects.at(objectIndex)
|
||||
.containerItems.at(itemIndex).actionCount;
|
||||
}
|
||||
|
||||
void WorldFunctions::SetEventCell(const char* cellDescription) noexcept
|
||||
{
|
||||
writeEvent.cell = Utils::getCellFromDescription(cellDescription);
|
||||
}
|
||||
|
||||
void WorldFunctions::SetEventAction(unsigned char action) noexcept
|
||||
{
|
||||
writeEvent.action = action;
|
||||
}
|
||||
|
||||
void WorldFunctions::SetObjectRefId(const char* refId) noexcept
|
||||
{
|
||||
tempWorldObject.refId = refId;
|
||||
}
|
||||
|
||||
void WorldFunctions::SetObjectRefNumIndex(int refNumIndex) noexcept
|
||||
{
|
||||
tempWorldObject.refNumIndex = refNumIndex;
|
||||
}
|
||||
|
||||
void WorldFunctions::SetObjectMpNum(int mpNum) noexcept
|
||||
{
|
||||
tempWorldObject.mpNum = mpNum;
|
||||
}
|
||||
|
||||
void WorldFunctions::SetObjectCount(int count) noexcept
|
||||
{
|
||||
tempWorldObject.count = count;
|
||||
}
|
||||
|
||||
void WorldFunctions::SetObjectCharge(int charge) noexcept
|
||||
{
|
||||
tempWorldObject.charge = charge;
|
||||
}
|
||||
|
||||
void WorldFunctions::SetObjectGoldValue(int goldValue) noexcept
|
||||
{
|
||||
tempWorldObject.goldValue = goldValue;
|
||||
}
|
||||
|
||||
void WorldFunctions::SetObjectScale(double scale) noexcept
|
||||
{
|
||||
tempWorldObject.scale = scale;
|
||||
}
|
||||
|
||||
void WorldFunctions::SetObjectState(bool objectState) noexcept
|
||||
{
|
||||
tempWorldObject.objectState = objectState;
|
||||
}
|
||||
|
||||
void WorldFunctions::SetObjectDoorState(int doorState) noexcept
|
||||
{
|
||||
tempWorldObject.doorState = doorState;
|
||||
}
|
||||
|
||||
void WorldFunctions::SetObjectLockLevel(int lockLevel) noexcept
|
||||
{
|
||||
tempWorldObject.lockLevel = lockLevel;
|
||||
}
|
||||
|
||||
void WorldFunctions::SetObjectDisarmState(bool disarmState) noexcept
|
||||
{
|
||||
tempWorldObject.isDisarmed = disarmState;
|
||||
}
|
||||
|
||||
void WorldFunctions::SetObjectMasterState(bool masterState) noexcept
|
||||
{
|
||||
tempWorldObject.hasMaster = masterState;
|
||||
}
|
||||
|
||||
void WorldFunctions::SetObjectPosition(double x, double y, double z) noexcept
|
||||
{
|
||||
tempWorldObject.position.pos[0] = x;
|
||||
tempWorldObject.position.pos[1] = y;
|
||||
tempWorldObject.position.pos[2] = z;
|
||||
}
|
||||
|
||||
void WorldFunctions::SetObjectRotation(double x, double y, double z) noexcept
|
||||
{
|
||||
tempWorldObject.position.rot[0] = x;
|
||||
tempWorldObject.position.rot[1] = y;
|
||||
tempWorldObject.position.rot[2] = z;
|
||||
}
|
||||
|
||||
void WorldFunctions::SetContainerItemRefId(const char* refId) noexcept
|
||||
{
|
||||
tempContainerItem.refId = refId;
|
||||
}
|
||||
|
||||
void WorldFunctions::SetContainerItemCount(int count) noexcept
|
||||
{
|
||||
tempContainerItem.count = count;
|
||||
}
|
||||
|
||||
void WorldFunctions::SetContainerItemCharge(int charge) noexcept
|
||||
{
|
||||
tempContainerItem.charge = charge;
|
||||
}
|
||||
|
||||
void WorldFunctions::AddWorldObject() noexcept
|
||||
{
|
||||
writeEvent.worldObjects.push_back(tempWorldObject);
|
||||
|
||||
tempWorldObject = emptyWorldObject;
|
||||
}
|
||||
|
||||
void WorldFunctions::AddContainerItem() noexcept
|
||||
{
|
||||
tempWorldObject.containerItems.push_back(tempContainerItem);
|
||||
|
||||
tempContainerItem = emptyContainerItem;
|
||||
}
|
||||
|
||||
void WorldFunctions::SendObjectPlace() noexcept
|
||||
{
|
||||
mwmp::Networking::get().getWorldPacketController()->GetPacket(ID_OBJECT_PLACE)->setEvent(&writeEvent);
|
||||
mwmp::Networking::get().getWorldPacketController()->GetPacket(ID_OBJECT_PLACE)->Send(writeEvent.guid);
|
||||
}
|
||||
|
||||
void WorldFunctions::SendObjectSpawn() noexcept
|
||||
{
|
||||
mwmp::Networking::get().getWorldPacketController()->GetPacket(ID_OBJECT_SPAWN)->setEvent(&writeEvent);
|
||||
mwmp::Networking::get().getWorldPacketController()->GetPacket(ID_OBJECT_SPAWN)->Send(writeEvent.guid);
|
||||
}
|
||||
|
||||
void WorldFunctions::SendObjectDelete() noexcept
|
||||
{
|
||||
mwmp::Networking::get().getWorldPacketController()->GetPacket(ID_OBJECT_DELETE)->setEvent(&writeEvent);
|
||||
mwmp::Networking::get().getWorldPacketController()->GetPacket(ID_OBJECT_DELETE)->Send(writeEvent.guid);
|
||||
}
|
||||
|
||||
void WorldFunctions::SendObjectLock() noexcept
|
||||
{
|
||||
mwmp::Networking::get().getWorldPacketController()->GetPacket(ID_OBJECT_LOCK)->setEvent(&writeEvent);
|
||||
mwmp::Networking::get().getWorldPacketController()->GetPacket(ID_OBJECT_LOCK)->Send(writeEvent.guid);
|
||||
}
|
||||
|
||||
void WorldFunctions::SendObjectTrap() noexcept
|
||||
{
|
||||
mwmp::Networking::get().getWorldPacketController()->GetPacket(ID_OBJECT_TRAP)->setEvent(&writeEvent);
|
||||
mwmp::Networking::get().getWorldPacketController()->GetPacket(ID_OBJECT_TRAP)->Send(writeEvent.guid);
|
||||
}
|
||||
|
||||
void WorldFunctions::SendObjectScale() noexcept
|
||||
{
|
||||
mwmp::Networking::get().getWorldPacketController()->GetPacket(ID_OBJECT_SCALE)->setEvent(&writeEvent);
|
||||
mwmp::Networking::get().getWorldPacketController()->GetPacket(ID_OBJECT_SCALE)->Send(writeEvent.guid);
|
||||
}
|
||||
|
||||
void WorldFunctions::SendObjectState() noexcept
|
||||
{
|
||||
mwmp::Networking::get().getWorldPacketController()->GetPacket(ID_OBJECT_STATE)->setEvent(&writeEvent);
|
||||
mwmp::Networking::get().getWorldPacketController()->GetPacket(ID_OBJECT_STATE)->Send(writeEvent.guid);
|
||||
}
|
||||
|
||||
void WorldFunctions::SendDoorState() noexcept
|
||||
{
|
||||
mwmp::Networking::get().getWorldPacketController()->GetPacket(ID_DOOR_STATE)->setEvent(&writeEvent);
|
||||
mwmp::Networking::get().getWorldPacketController()->GetPacket(ID_DOOR_STATE)->Send(writeEvent.guid);
|
||||
}
|
||||
|
||||
void WorldFunctions::SendContainer() noexcept
|
||||
{
|
||||
mwmp::Networking::get().getWorldPacketController()->GetPacket(ID_CONTAINER)->setEvent(&writeEvent);
|
||||
mwmp::Networking::get().getWorldPacketController()->GetPacket(ID_CONTAINER)->Send(writeEvent.guid);
|
||||
}
|
||||
|
||||
void WorldFunctions::SetHour(unsigned short pid, double hour) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
|
||||
player->hour = hour;
|
||||
player->month = -1;
|
||||
player->day = -1;
|
||||
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_GAME_TIME)->setPlayer(player);
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_GAME_TIME)->Send(false);
|
||||
}
|
||||
|
||||
void WorldFunctions::SetMonth(unsigned short pid, int month) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
|
||||
player->hour = -1;
|
||||
player->month = month;
|
||||
player->day = -1;
|
||||
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_GAME_TIME)->setPlayer(player);
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_GAME_TIME)->Send(false);
|
||||
|
||||
}
|
||||
|
||||
void WorldFunctions::SetDay(unsigned short pid, int day) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
|
||||
player->hour = -1;
|
||||
player->month = -1;
|
||||
player->day = day;
|
||||
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_GAME_TIME)->setPlayer(player);
|
||||
mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_GAME_TIME)->Send(false);
|
||||
}
|
@ -1,615 +0,0 @@
|
||||
#ifndef OPENMW_WORLDAPI_HPP
|
||||
#define OPENMW_WORLDAPI_HPP
|
||||
|
||||
#define WORLDAPI \
|
||||
{"ReadLastEvent", WorldFunctions::ReadLastEvent},\
|
||||
{"InitializeEvent", WorldFunctions::InitializeEvent},\
|
||||
\
|
||||
{"GetObjectChangesSize", WorldFunctions::GetObjectChangesSize},\
|
||||
{"GetEventAction", WorldFunctions::GetEventAction},\
|
||||
\
|
||||
{"GetObjectRefId", WorldFunctions::GetObjectRefId},\
|
||||
{"GetObjectRefNumIndex", WorldFunctions::GetObjectRefNumIndex},\
|
||||
{"GetObjectMpNum", WorldFunctions::GetObjectMpNum},\
|
||||
{"GetObjectCount", WorldFunctions::GetObjectCount},\
|
||||
{"GetObjectCharge", WorldFunctions::GetObjectCharge},\
|
||||
{"GetObjectGoldValue", WorldFunctions::GetObjectGoldValue},\
|
||||
{"GetObjectScale", WorldFunctions::GetObjectScale},\
|
||||
{"GetObjectState", WorldFunctions::GetObjectState},\
|
||||
{"GetObjectDoorState", WorldFunctions::GetObjectDoorState},\
|
||||
{"GetObjectLockLevel", WorldFunctions::GetObjectLockLevel},\
|
||||
{"GetObjectPosX", WorldFunctions::GetObjectPosX},\
|
||||
{"GetObjectPosY", WorldFunctions::GetObjectPosY},\
|
||||
{"GetObjectPosZ", WorldFunctions::GetObjectPosZ},\
|
||||
{"GetObjectRotX", WorldFunctions::GetObjectRotX},\
|
||||
{"GetObjectRotY", WorldFunctions::GetObjectRotY},\
|
||||
{"GetObjectRotZ", WorldFunctions::GetObjectRotZ},\
|
||||
\
|
||||
{"GetContainerChangesSize", WorldFunctions::GetContainerChangesSize},\
|
||||
{"GetContainerItemRefId", WorldFunctions::GetContainerItemRefId},\
|
||||
{"GetContainerItemCount", WorldFunctions::GetContainerItemCount},\
|
||||
{"GetContainerItemCharge", WorldFunctions::GetContainerItemCharge},\
|
||||
{"GetContainerItemActionCount", WorldFunctions::GetContainerItemActionCount},\
|
||||
\
|
||||
{"SetEventCell", WorldFunctions::SetEventCell},\
|
||||
{"SetEventAction", WorldFunctions::SetEventAction},\
|
||||
\
|
||||
{"SetObjectRefId", WorldFunctions::SetObjectRefId},\
|
||||
{"SetObjectRefNumIndex", WorldFunctions::SetObjectRefNumIndex},\
|
||||
{"SetObjectMpNum", WorldFunctions::SetObjectMpNum},\
|
||||
{"SetObjectCount", WorldFunctions::SetObjectCount},\
|
||||
{"SetObjectCharge", WorldFunctions::SetObjectCharge},\
|
||||
{"SetObjectGoldValue", WorldFunctions::SetObjectGoldValue},\
|
||||
{"SetObjectScale", WorldFunctions::SetObjectScale},\
|
||||
{"SetObjectState", WorldFunctions::SetObjectState},\
|
||||
{"SetObjectDoorState", WorldFunctions::SetObjectDoorState},\
|
||||
{"SetObjectLockLevel", WorldFunctions::SetObjectLockLevel},\
|
||||
{"SetObjectDisarmState", WorldFunctions::SetObjectDisarmState},\
|
||||
{"SetObjectMasterState", WorldFunctions::SetObjectMasterState},\
|
||||
{"SetObjectPosition", WorldFunctions::SetObjectPosition},\
|
||||
{"SetObjectRotation", WorldFunctions::SetObjectRotation},\
|
||||
\
|
||||
{"SetContainerItemRefId", WorldFunctions::SetContainerItemRefId},\
|
||||
{"SetContainerItemCount", WorldFunctions::SetContainerItemCount},\
|
||||
{"SetContainerItemCharge", WorldFunctions::SetContainerItemCharge},\
|
||||
\
|
||||
{"AddWorldObject", WorldFunctions::AddWorldObject},\
|
||||
{"AddContainerItem", WorldFunctions::AddContainerItem},\
|
||||
\
|
||||
{"SendObjectPlace", WorldFunctions::SendObjectPlace},\
|
||||
{"SendObjectSpawn", WorldFunctions::SendObjectSpawn},\
|
||||
{"SendObjectDelete", WorldFunctions::SendObjectDelete},\
|
||||
{"SendObjectLock", WorldFunctions::SendObjectLock},\
|
||||
{"SendObjectTrap", WorldFunctions::SendObjectTrap},\
|
||||
{"SendObjectScale", WorldFunctions::SendObjectScale},\
|
||||
{"SendObjectState", WorldFunctions::SendObjectState},\
|
||||
{"SendDoorState", WorldFunctions::SendDoorState},\
|
||||
{"SendContainer", WorldFunctions::SendContainer},\
|
||||
\
|
||||
{"SetHour", WorldFunctions::SetHour},\
|
||||
{"SetMonth", WorldFunctions::SetMonth},\
|
||||
{"SetDay", WorldFunctions::SetDay}
|
||||
|
||||
class WorldFunctions
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* \brief Use the last event received by the server as the one being read.
|
||||
*
|
||||
* \return void
|
||||
*/
|
||||
static void ReadLastEvent() noexcept;
|
||||
|
||||
/**
|
||||
* \brief Clear the data from the last event sent by the server.
|
||||
*
|
||||
* This is used to initialize the sending of new Object packets.
|
||||
*
|
||||
* \param pid The player ID to whom the event should be attached.
|
||||
* \return void
|
||||
*/
|
||||
static void InitializeEvent(unsigned short pid) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the number of indexes in the read event's object changes.
|
||||
*
|
||||
* \return The number of indexes.
|
||||
*/
|
||||
static unsigned int GetObjectChangesSize() noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the action type used in the read event.
|
||||
*
|
||||
* \return The action type (0 for SET, 1 for ADD, 2 for REMOVE, 3 for REQUEST).
|
||||
*/
|
||||
static unsigned char GetEventAction() noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the refId of the object at a certain index in the read event's object changes.
|
||||
*
|
||||
* \return The refId.
|
||||
*/
|
||||
static const char *GetObjectRefId(unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the refNumIndex of the object at a certain index in the read event's object
|
||||
* changes.
|
||||
*
|
||||
* \param i The index of the object.
|
||||
* \return The refNumIndex.
|
||||
*/
|
||||
static int GetObjectRefNumIndex(unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the mpNum of the object at a certain index in the read event's object changes.
|
||||
*
|
||||
* \param i The index of the object.
|
||||
* \return The mpNum.
|
||||
*/
|
||||
static int GetObjectMpNum(unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the count of the object at a certain index in the read event's object changes.
|
||||
*
|
||||
* \param i The index of the object.
|
||||
* \return The object count.
|
||||
*/
|
||||
static int GetObjectCount(unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the charge of the object at a certain index in the read event's object changes.
|
||||
*
|
||||
* \param i The index of the object.
|
||||
* \return The charge.
|
||||
*/
|
||||
static int GetObjectCharge(unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the gold value of the object at a certain index in the read event's object
|
||||
* changes.
|
||||
*
|
||||
* This is used solely to get the gold value of gold. It is not used for other objects.
|
||||
*
|
||||
* \param i The index of the object.
|
||||
* \return The gold value.
|
||||
*/
|
||||
static int GetObjectGoldValue(unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the object scale of the object at a certain index in the read event's object
|
||||
* changes.
|
||||
*
|
||||
* \param i The index of the object.
|
||||
* \return The object scale.
|
||||
*/
|
||||
static double GetObjectScale(unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the object state of the object at a certain index in the read event's object
|
||||
* changes.
|
||||
*
|
||||
* \param i The index of the object.
|
||||
* \return The object state.
|
||||
*/
|
||||
static bool GetObjectState(unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the door state of the object at a certain index in the read event's object
|
||||
* changes.
|
||||
*
|
||||
* \param i The index of the object.
|
||||
* \return The door state.
|
||||
*/
|
||||
static int GetObjectDoorState(unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the lock level of the object at a certain index in the read event's object
|
||||
* changes.
|
||||
*
|
||||
* \param i The index of the object.
|
||||
* \return The lock level.
|
||||
*/
|
||||
static int GetObjectLockLevel(unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the X position of the object at a certain index in the read event's object
|
||||
* changes.
|
||||
*
|
||||
* \param i The index of the object.
|
||||
* \return The X position.
|
||||
*/
|
||||
static double GetObjectPosX(unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the Y position of the object at a certain index in the read event's object
|
||||
* changes.
|
||||
*
|
||||
* \param i The index of the object.
|
||||
* \return The Y position.
|
||||
*/
|
||||
static double GetObjectPosY(unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the Z position at a certain index in the read event's object changes.
|
||||
*
|
||||
* \param i The index of the object.
|
||||
* \return The Z position.
|
||||
*/
|
||||
static double GetObjectPosZ(unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the X rotation of the object at a certain index in the read event's object
|
||||
* changes.
|
||||
*
|
||||
* \param i The index of the object.
|
||||
* \return The X rotation.
|
||||
*/
|
||||
static double GetObjectRotX(unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the Y rotation of the object at a certain index in the read event's object
|
||||
* changes.
|
||||
*
|
||||
* \param i The index of the object.
|
||||
* \return The Y rotation.
|
||||
*/
|
||||
static double GetObjectRotY(unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the Z rotation of the object at a certain index in the read event's object
|
||||
* changes.
|
||||
*
|
||||
* \param i The index of the object.
|
||||
* \return The Z rotation.
|
||||
*/
|
||||
static double GetObjectRotZ(unsigned int i) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the number of container item indexes of the object at a certain index in the
|
||||
* read event's object changes.
|
||||
*
|
||||
* \param i The index of the object.
|
||||
* \return The number of container item indexes.
|
||||
*/
|
||||
static unsigned int GetContainerChangesSize(unsigned int objectIndex) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the refId of the container item at a certain itemIndex in the container changes
|
||||
* of the object at a certain objectIndex in the read event's object changes.
|
||||
*
|
||||
* \param objectIndex The index of the object.
|
||||
* \param itemIndex The index of the container item.
|
||||
* \return The refId.
|
||||
*/
|
||||
static const char *GetContainerItemRefId(unsigned int objectIndex, unsigned int itemIndex) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the item count of the container item at a certain itemIndex in the container
|
||||
* changes of the object at a certain objectIndex in the read event's object changes.
|
||||
*
|
||||
* \param objectIndex The index of the object.
|
||||
* \param itemIndex The index of the container item.
|
||||
* \return The item count.
|
||||
*/
|
||||
static int GetContainerItemCount(unsigned int objectIndex, unsigned int itemIndex) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the charge of the container item at a certain itemIndex in the container changes
|
||||
* of the object at a certain objectIndex in the read event's object changes.
|
||||
*
|
||||
* \param objectIndex The index of the object.
|
||||
* \param itemIndex The index of the container item.
|
||||
* \return The charge.
|
||||
*/
|
||||
static int GetContainerItemCharge(unsigned int objectIndex, unsigned int itemIndex) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Get the action count of the container item at a certain itemIndex in the container
|
||||
* changes of the object at a certain objectIndex in the read event's object changes.
|
||||
*
|
||||
* \param objectIndex The index of the object.
|
||||
* \param itemIndex The index of the container item.
|
||||
* \return The action count.
|
||||
*/
|
||||
static int GetContainerItemActionCount(unsigned int objectIndex, unsigned int itemIndex) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the cell of the temporary event stored on the server.
|
||||
*
|
||||
* The cell is determined to be an exterior cell if it fits the pattern of a number followed
|
||||
* by a comma followed by another number.
|
||||
*
|
||||
* \param cellDescription The description of the cell.
|
||||
* \return void
|
||||
*/
|
||||
static void SetEventCell(const char* cellDescription) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the action type of the temporary event stored on the server.
|
||||
*
|
||||
* \param action The action type (0 for SET, 1 for ADD, 2 for REMOVE, 3 for REQUEST).
|
||||
* \return void
|
||||
*/
|
||||
static void SetEventAction(unsigned char action) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the refId of the temporary world object stored on the server.
|
||||
*
|
||||
* \param refId The refId.
|
||||
* \return void
|
||||
*/
|
||||
static void SetObjectRefId(const char* refId) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the refNumIndex of the temporary world object stored on the server.
|
||||
*
|
||||
* Every object loaded from .ESM and .ESP data files has a unique refNumIndex which needs to be
|
||||
* retained to refer to it in packets.
|
||||
*
|
||||
* On the other hand, objects placed or spawned via the server should always have a refNumIndex
|
||||
* of 0.
|
||||
*
|
||||
* \param refNumIndex The refNumIndex.
|
||||
* \return void
|
||||
*/
|
||||
static void SetObjectRefNumIndex(int refNumIndex) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the mpNum of the temporary world object stored on the server.
|
||||
*
|
||||
* Every object placed or spawned via the server is assigned an mpNum by incrementing the last
|
||||
* mpNum stored on the server. Scripts should take care to ensure that mpNums are kept unique
|
||||
* for these objects.
|
||||
*
|
||||
* Objects loaded from .ESM and .ESP data files should always have an mpNum of 0, because they
|
||||
* have unique refNumIndexes instead.
|
||||
*
|
||||
* \param mpNum The mpNum.
|
||||
* \return void
|
||||
*/
|
||||
static void SetObjectMpNum(int mpNum) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the object count of the temporary world object stored on the server.
|
||||
*
|
||||
* This determines the quantity of an object, with the exception of gold.
|
||||
*
|
||||
* \param count The object count.
|
||||
* \return void
|
||||
*/
|
||||
static void SetObjectCount(int count) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the charge of the temporary world object stored on the server.
|
||||
*
|
||||
* Object durabilities are set through this value.
|
||||
*
|
||||
* \param charge The charge.
|
||||
* \return void
|
||||
*/
|
||||
static void SetObjectCharge(int charge) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the gold value of the temporary world object stored on the server.
|
||||
*
|
||||
* This is used solely to set the gold value for gold. It has no effect on other objects.
|
||||
*
|
||||
* \param goldValue The gold value.
|
||||
* \return void
|
||||
*/
|
||||
static void SetObjectGoldValue(int goldValue) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the scale of the temporary world object stored on the server.
|
||||
*
|
||||
* Objects are smaller or larger than their default size based on their scale.
|
||||
*
|
||||
* \param scale The scale.
|
||||
* \return void
|
||||
*/
|
||||
static void SetObjectScale(double scale) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the object state of the temporary world object stored on the server.
|
||||
*
|
||||
* Objects are enabled or disabled based on their object state.
|
||||
*
|
||||
* \param objectState The object state.
|
||||
* \return void
|
||||
*/
|
||||
static void SetObjectState(bool objectState) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the door state of the temporary world object stored on the server.
|
||||
*
|
||||
* Doors are open or closed based on their door state.
|
||||
*
|
||||
* \param doorState The door state.
|
||||
* \return void
|
||||
*/
|
||||
static void SetObjectDoorState(int doorState) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the lock level of the temporary world object stored on the server.
|
||||
*
|
||||
* \param lockLevel The lock level.
|
||||
* \return void
|
||||
*/
|
||||
static void SetObjectLockLevel(int lockLevel) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the disarm state of the temporary world object stored on the server.
|
||||
*
|
||||
* \param disarmState The disarmState.
|
||||
* \return void
|
||||
*/
|
||||
static void SetObjectDisarmState(bool disarmState) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the master state of the temporary world object stored on the server.
|
||||
*
|
||||
* This only affects living actors and determines whether they are followers of another
|
||||
* living actor.
|
||||
*
|
||||
* \param masterState The master state.
|
||||
* \return void
|
||||
*/
|
||||
static void SetObjectMasterState(bool masterState) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the position of the temporary world object stored on the server.
|
||||
*
|
||||
* \param x The X position.
|
||||
* \param y The Y position.
|
||||
* \param z The Z position.
|
||||
* \return void
|
||||
*/
|
||||
static void SetObjectPosition(double x, double y, double z) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the rotation of the temporary world object stored on the server.
|
||||
*
|
||||
* \param x The X rotation.
|
||||
* \param y The Y rotation.
|
||||
* \param z The Z rotation.
|
||||
* \return void
|
||||
*/
|
||||
static void SetObjectRotation(double x, double y, double z) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the refId of the temporary container item stored on the server.
|
||||
*
|
||||
* \param refId The refId.
|
||||
* \return void
|
||||
*/
|
||||
static void SetContainerItemRefId(const char* refId) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the item count of the temporary container item stored on the server.
|
||||
*
|
||||
* \param count The item count.
|
||||
* \return void
|
||||
*/
|
||||
static void SetContainerItemCount(int count) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the charge of the temporary container item stored on the server.
|
||||
*
|
||||
* \param charge The charge.
|
||||
* \return void
|
||||
*/
|
||||
static void SetContainerItemCharge(int charge) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Add a copy of the server's temporary world object to the server's temporary event.
|
||||
*
|
||||
* In the process, the server's temporary world object will automatically be cleared so a new
|
||||
* one can be set up.
|
||||
*
|
||||
* \return void
|
||||
*/
|
||||
static void AddWorldObject() noexcept;
|
||||
|
||||
/**
|
||||
* \brief Add a copy of the server's temporary container item to the container changes of the
|
||||
* server's temporary world object.
|
||||
*
|
||||
* In the process, the server's temporary container item will automatically be cleared so a new
|
||||
* one can be set up.
|
||||
*
|
||||
* \return void
|
||||
*/
|
||||
static void AddContainerItem() noexcept;
|
||||
|
||||
/**
|
||||
* \brief Send an ObjectPlace packet.
|
||||
*
|
||||
* It is sent only to the player for whom the current event was initialized.
|
||||
*
|
||||
* \return void
|
||||
*/
|
||||
static void SendObjectPlace() noexcept;
|
||||
|
||||
/**
|
||||
* \brief Send an ObjectSpawn packet.
|
||||
*
|
||||
* It is sent only to the player for whom the current event was initialized.
|
||||
*
|
||||
* \return void
|
||||
*/
|
||||
static void SendObjectSpawn() noexcept;
|
||||
|
||||
/**
|
||||
* \brief Send an ObjectDelete packet.
|
||||
*
|
||||
* It is sent only to the player for whom the current event was initialized.
|
||||
*
|
||||
* \return void
|
||||
*/
|
||||
static void SendObjectDelete() noexcept;
|
||||
|
||||
/**
|
||||
* \brief Send an ObjectLock packet.
|
||||
*
|
||||
* It is sent only to the player for whom the current event was initialized.
|
||||
*
|
||||
* \return void
|
||||
*/
|
||||
static void SendObjectLock() noexcept;
|
||||
|
||||
/**
|
||||
* \brief Send an ObjectTrap packet.
|
||||
*
|
||||
* It is sent only to the player for whom the current event was initialized.
|
||||
*
|
||||
* \return void
|
||||
*/
|
||||
static void SendObjectTrap() noexcept;
|
||||
|
||||
/**
|
||||
* \brief Send an ObjectScale packet.
|
||||
*
|
||||
* It is sent only to the player for whom the current event was initialized.
|
||||
*
|
||||
* \return void
|
||||
*/
|
||||
static void SendObjectScale() noexcept;
|
||||
|
||||
/**
|
||||
* \brief Send an ObjectState packet.
|
||||
*
|
||||
* It is sent only to the player for whom the current event was initialized.
|
||||
*
|
||||
* \return void
|
||||
*/
|
||||
static void SendObjectState() noexcept;
|
||||
|
||||
/**
|
||||
* \brief Send a DoorState packet.
|
||||
*
|
||||
* It is sent only to the player for whom the current event was initialized.
|
||||
*
|
||||
* \return void
|
||||
*/
|
||||
static void SendDoorState() noexcept;
|
||||
|
||||
/**
|
||||
* \brief Send a Container packet.
|
||||
*
|
||||
* It is sent only to the player for whom the current event was initialized.
|
||||
*
|
||||
* \return void
|
||||
*/
|
||||
static void SendContainer() noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the game hour for a player and send a GameTime packet to that player.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \param hour The hour.
|
||||
* \return void
|
||||
*/
|
||||
static void SetHour(unsigned short pid, double hour) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the game month for a player and send a GameTime packet to that player.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \param month The month.
|
||||
* \return void
|
||||
*/
|
||||
static void SetMonth(unsigned short pid, int month) noexcept;
|
||||
|
||||
/**
|
||||
* \brief Set the game day for a player and send a GameTime packet to that player.
|
||||
*
|
||||
* \param pid The player ID.
|
||||
* \param day The day.
|
||||
* \return void
|
||||
*/
|
||||
static void SetDay(unsigned short pid, int day) noexcept;
|
||||
};
|
||||
|
||||
|
||||
#endif //OPENMW_WORLDAPI_HPP
|
@ -1,198 +0,0 @@
|
||||
//
|
||||
// Created by koncord on 08.05.16.
|
||||
//
|
||||
|
||||
#include <iostream>
|
||||
#include "LangLua.hpp"
|
||||
#include <Script/Script.hpp>
|
||||
#include <Script/Types.hpp>
|
||||
|
||||
using namespace std;
|
||||
|
||||
lib_t LangLua::GetInterface()
|
||||
{
|
||||
return reinterpret_cast<lib_t>(lua);
|
||||
}
|
||||
|
||||
LangLua::LangLua(lua_State *lua)
|
||||
{
|
||||
this->lua = lua;
|
||||
}
|
||||
|
||||
LangLua::LangLua()
|
||||
{
|
||||
lua = luaL_newstate();
|
||||
luaL_openlibs(lua); // load all lua std libs
|
||||
#if defined(ENABLE_TERRA)
|
||||
terra_init(lua);
|
||||
#endif
|
||||
}
|
||||
|
||||
LangLua::~LangLua()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
template<unsigned int I, unsigned int F>
|
||||
struct Lua_dispatch_ {
|
||||
template<typename R, typename... Args>
|
||||
inline static R Lua_dispatch(lua_State*&& lua, Args&&... args) noexcept {
|
||||
constexpr ScriptFunctionData const& F_ = ScriptFunctions::functions[F];
|
||||
auto arg = luabridge::Stack<typename CharType<F_.func.types[I - 1]>::type>::get(lua, I);
|
||||
return Lua_dispatch_<I - 1, F>::template Lua_dispatch<R>(
|
||||
forward<lua_State*>(lua),
|
||||
arg,
|
||||
forward<Args>(args)...);
|
||||
}
|
||||
};
|
||||
|
||||
template<unsigned int F>
|
||||
struct Lua_dispatch_<0, F> {
|
||||
template<typename R, typename... Args>
|
||||
inline static R Lua_dispatch(lua_State*&&, Args&&... args) noexcept {
|
||||
constexpr ScriptFunctionData const& F_ = ScriptFunctions::functions[F];
|
||||
return reinterpret_cast<FunctionEllipsis<R>>(F_.func.addr)(forward<Args>(args)...);
|
||||
}
|
||||
};
|
||||
|
||||
template<unsigned int I>
|
||||
static typename enable_if<ScriptFunctions::functions[I].func.ret == 'v', int>::type wrapper(lua_State* lua) noexcept {
|
||||
Lua_dispatch_<ScriptFunctions::functions[I].func.numargs, I>::template Lua_dispatch<void>(forward<lua_State*>(lua));
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<unsigned int I>
|
||||
static typename enable_if<ScriptFunctions::functions[I].func.ret != 'v', int>::type wrapper(lua_State* lua) noexcept {
|
||||
auto ret = Lua_dispatch_<ScriptFunctions::functions[I].func.numargs, I>::template Lua_dispatch<
|
||||
typename CharType<ScriptFunctions::functions[I].func.ret>::type>(forward<lua_State*>(lua));
|
||||
luabridge::Stack <typename CharType<ScriptFunctions::functions[I].func.ret>::type>::push (lua, ret);
|
||||
return 1;
|
||||
}
|
||||
|
||||
template<unsigned int I>
|
||||
struct F_
|
||||
{
|
||||
static constexpr LuaFuctionData F{ScriptFunctions::functions[I].name, wrapper<I>};
|
||||
};
|
||||
|
||||
|
||||
template<> struct F_<0> { static constexpr LuaFuctionData F{"CreateTimer", LangLua::CreateTimer}; };
|
||||
template<> struct F_<1> { static constexpr LuaFuctionData F{"CreateTimerEx", LangLua::CreateTimerEx}; };
|
||||
template<> struct F_<2> { static constexpr LuaFuctionData F{"MakePublic", LangLua::MakePublic}; };
|
||||
template<> struct F_<3> { static constexpr LuaFuctionData F{"CallPublic", LangLua::CallPublic}; };
|
||||
|
||||
template<size_t... Indices>
|
||||
inline LuaFuctionData *LangLua::functions(indices<Indices...>)
|
||||
{
|
||||
|
||||
static LuaFuctionData functions_[sizeof...(Indices)]{
|
||||
F_<Indices>::F...
|
||||
};
|
||||
|
||||
static_assert(
|
||||
sizeof(functions_) / sizeof(functions_[0]) ==
|
||||
sizeof(ScriptFunctions::functions) / sizeof(ScriptFunctions::functions[0]),
|
||||
"Not all functions have been mapped to Lua");
|
||||
|
||||
return functions_;
|
||||
}
|
||||
|
||||
void LangLua::LoadProgram(const char *filename)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
#if defined(ENABLE_TERRA)
|
||||
if ((err = terra_loadfile(lua, filename)) != 0)
|
||||
#else
|
||||
if ((err =luaL_loadfile(lua, filename)) != 0)
|
||||
#endif
|
||||
throw runtime_error("Lua script " + string(filename) + " error (" + to_string(err) + "): \"" +
|
||||
string(lua_tostring(lua, -1)) + "\"");
|
||||
|
||||
constexpr auto functions_n = sizeof(ScriptFunctions::functions) / sizeof(ScriptFunctions::functions[0]);
|
||||
|
||||
LuaFuctionData *functions_ = functions(IndicesFor<functions_n>{});
|
||||
|
||||
luabridge::Namespace tes3mp = luabridge::getGlobalNamespace(lua).beginNamespace("tes3mp");
|
||||
|
||||
for (unsigned i = 0; i < functions_n; i++)
|
||||
tes3mp.addCFunction(functions_[i].name, functions_[i].func);
|
||||
|
||||
tes3mp.endNamespace();
|
||||
|
||||
if ((err = lua_pcall(lua, 0, 0, 0)) != 0) // Run once script for load in memory.
|
||||
throw runtime_error("Lua script " + string(filename) + " error (" + to_string(err) + "): \"" +
|
||||
string(lua_tostring(lua, -1)) + "\"");
|
||||
}
|
||||
|
||||
int LangLua::FreeProgram()
|
||||
{
|
||||
lua_close(lua);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool LangLua::IsCallbackPresent(const char *name)
|
||||
{
|
||||
return luabridge::getGlobal(lua, name).isFunction();
|
||||
}
|
||||
|
||||
boost::any LangLua::Call(const char *name, const char *argl, int buf, ...)
|
||||
{
|
||||
va_list vargs;
|
||||
va_start(vargs, buf);
|
||||
std::vector<boost::any> args;
|
||||
|
||||
ScriptFunctions::GetArguments(args, vargs, argl);
|
||||
|
||||
return Call(name, argl, args);
|
||||
}
|
||||
|
||||
boost::any LangLua::Call(const char *name, const char *argl, const std::vector<boost::any> &args)
|
||||
{
|
||||
int n_args = (int)(strlen(argl)) ;
|
||||
|
||||
lua_getglobal (lua, name);
|
||||
|
||||
for (intptr_t i = 0; i < n_args; i++)
|
||||
{
|
||||
switch (argl[i])
|
||||
{
|
||||
case 'i':
|
||||
luabridge::Stack<unsigned int>::push(lua, boost::any_cast<unsigned int>(args.at(i)));
|
||||
break;
|
||||
|
||||
case 'q':
|
||||
luabridge::Stack<signed int>::push(lua, boost::any_cast<signed int>(args.at(i)));
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
luabridge::Stack<unsigned long long>::push(lua, boost::any_cast<unsigned long long>(args.at(i)));
|
||||
break;
|
||||
|
||||
case 'w':
|
||||
luabridge::Stack<signed long long>::push(lua, boost::any_cast<signed long long>(args.at(i)));
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
luabridge::Stack<double>::push(lua, boost::any_cast<double>(args.at(i)));
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
luabridge::Stack<void *>::push(lua, boost::any_cast<void *>(args.at(i)));
|
||||
break;
|
||||
|
||||
case 's':
|
||||
luabridge::Stack<const char *>::push(lua, boost::any_cast<const char *>(args.at(i)));
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
luabridge::Stack<bool>::push(lua, boost::any_cast<int>(args.at(i)));
|
||||
break;
|
||||
default:
|
||||
throw runtime_error("Lua call: Unknown argument identifier " + argl[i]);
|
||||
}
|
||||
}
|
||||
|
||||
luabridge::LuaException::pcall (lua, n_args, 1);
|
||||
return boost::any(luabridge::LuaRef::fromStack(lua, -1));
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
//
|
||||
// Created by koncord on 08.05.16.
|
||||
//
|
||||
|
||||
#ifndef PLUGINSYSTEM3_LANGLUA_HPP
|
||||
#define PLUGINSYSTEM3_LANGLUA_HPP
|
||||
|
||||
#ifdef ENABLE_TERRA
|
||||
#include <terra/terra.h>
|
||||
#else
|
||||
#include "lua.hpp"
|
||||
#endif
|
||||
|
||||
#include <extern/LuaBridge/LuaBridge.h>
|
||||
#include <LuaBridge.h>
|
||||
|
||||
#include <boost/any.hpp>
|
||||
#include "../ScriptFunction.hpp"
|
||||
#include "../Language.hpp"
|
||||
|
||||
struct LuaFuctionData
|
||||
{
|
||||
const char* name;
|
||||
lua_CFunction func;
|
||||
};
|
||||
|
||||
class LangLua: public Language
|
||||
{
|
||||
private:
|
||||
template<std::size_t... Is>
|
||||
struct indices {};
|
||||
template<std::size_t N, std::size_t... Is>
|
||||
struct build_indices : build_indices<N-1, N-1, Is...> {};
|
||||
template<std::size_t... Is>
|
||||
struct build_indices<0, Is...> : indices<Is...> {};
|
||||
template<std::size_t N>
|
||||
using IndicesFor = build_indices<N>;
|
||||
|
||||
public:
|
||||
virtual lib_t GetInterface() override;
|
||||
template<std::size_t... Indices>
|
||||
static LuaFuctionData* functions(indices<Indices...>);
|
||||
lua_State *lua;
|
||||
public:
|
||||
LangLua();
|
||||
LangLua(lua_State *lua);
|
||||
~LangLua();
|
||||
static int MakePublic(lua_State *lua) noexcept;
|
||||
static int CallPublic(lua_State *lua);
|
||||
|
||||
static int CreateTimer(lua_State *lua) noexcept;
|
||||
static int CreateTimerEx(lua_State *lua);
|
||||
|
||||
virtual void LoadProgram(const char *filename) override;
|
||||
virtual int FreeProgram() override;
|
||||
virtual bool IsCallbackPresent(const char *name) override;
|
||||
virtual boost::any Call(const char *name, const char *argl, int buf, ...) override;
|
||||
virtual boost::any Call(const char *name, const char *argl, const std::vector<boost::any> &args) override;
|
||||
};
|
||||
|
||||
|
||||
#endif //PLUGINSYSTEM3_LANGLUA_HPP
|
@ -1,182 +0,0 @@
|
||||
//
|
||||
// Created by koncord on 09.05.16.
|
||||
//
|
||||
|
||||
#include <iostream>
|
||||
#include "LangLua.hpp"
|
||||
#include <Script/API/TimerAPI.hpp>
|
||||
#include <Script/API/PublicFnAPI.hpp>
|
||||
|
||||
using namespace std;
|
||||
|
||||
inline vector<boost::any> DefToVec(lua_State *lua, string types, int args_begin, int args_n)
|
||||
{
|
||||
vector<boost::any> args;
|
||||
|
||||
for (int i = args_begin; i < args_n + args_begin; i++)
|
||||
{
|
||||
switch (types[i - args_begin])
|
||||
{
|
||||
case 'i':
|
||||
{
|
||||
args.emplace_back(luabridge::Stack<unsigned int>::get(lua, i));
|
||||
break;
|
||||
}
|
||||
|
||||
case 'q':
|
||||
{
|
||||
args.emplace_back(luabridge::Stack<signed int>::get(lua, i));
|
||||
break;
|
||||
}
|
||||
|
||||
/*case 'l':
|
||||
{
|
||||
args.emplace_back(luabridge::Stack<unsigned long long>::get(lua, i));
|
||||
break;
|
||||
}
|
||||
|
||||
case 'w':
|
||||
{
|
||||
args.emplace_back(luabridge::Stack<signed long long>::get(lua, i));
|
||||
break;
|
||||
}*/
|
||||
|
||||
case 'f':
|
||||
{
|
||||
args.emplace_back(luabridge::Stack<double>::get(lua, i));
|
||||
break;
|
||||
}
|
||||
|
||||
case 's':
|
||||
{
|
||||
args.emplace_back(luabridge::Stack<const char*>::get(lua, i));
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
stringstream ssErr;
|
||||
ssErr << "Lua: Unknown argument identifier" << "\"" << types[i] << "\"" << endl;
|
||||
throw std::runtime_error(ssErr.str());
|
||||
}
|
||||
}
|
||||
}
|
||||
return args;
|
||||
}
|
||||
|
||||
int LangLua::MakePublic(lua_State *lua) noexcept
|
||||
{
|
||||
const char * callback = luabridge::Stack<const char*>::get(lua, 1);
|
||||
const char * name = luabridge::Stack<const char*>::get(lua, 2);
|
||||
char ret_type = luabridge::Stack<char>::get(lua, 3);
|
||||
const char * def = luabridge::Stack<const char*>::get(lua, 4);
|
||||
|
||||
Public::MakePublic(callback, lua, name, ret_type, def);
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int LangLua::CallPublic(lua_State *lua)
|
||||
{
|
||||
const char * name = luabridge::Stack<const char*>::get(lua, 1);
|
||||
|
||||
int args_n = lua_gettop(lua) - 1;
|
||||
|
||||
string types = Public::GetDefinition(name);
|
||||
|
||||
if (args_n != (long)types.size())
|
||||
throw invalid_argument("Script call: Number of arguments does not match definition");
|
||||
|
||||
vector<boost::any> args = DefToVec(lua, types, 2, args_n);
|
||||
|
||||
boost::any result = Public::Call(&name[0], args);
|
||||
if (result.empty())
|
||||
return 0;
|
||||
|
||||
if (result.type().hash_code() == typeid(signed int).hash_code())
|
||||
luabridge::Stack<signed int>::push(lua, boost::any_cast<signed int>(result));
|
||||
else if (result.type().hash_code() == typeid(unsigned int).hash_code())
|
||||
luabridge::Stack<unsigned int>::push(lua, boost::any_cast<unsigned int>(result));
|
||||
else if (result.type().hash_code() == typeid(double).hash_code())
|
||||
luabridge::Stack<double>::push(lua, boost::any_cast<double>(result));
|
||||
else if (result.type().hash_code() == typeid(const char*).hash_code())
|
||||
luabridge::Stack<const char*>::push(lua, boost::any_cast<const char*>(result));
|
||||
return 1;
|
||||
}
|
||||
|
||||
int LangLua::CreateTimer(lua_State *lua) noexcept
|
||||
{
|
||||
|
||||
const char * callback= luabridge::Stack<const char*>::get(lua, 1);
|
||||
int msec = luabridge::Stack<int>::get(lua, 2);
|
||||
|
||||
int id = mwmp::TimerAPI::CreateTimerLua(lua, callback, msec, "", vector<boost::any>());
|
||||
luabridge::push(lua, id);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int LangLua::CreateTimerEx(lua_State *lua)
|
||||
{
|
||||
const char * callback = luabridge::Stack<const char*>::get(lua, 1);
|
||||
int msec = luabridge::Stack<int>::get(lua, 2);
|
||||
|
||||
const char * types = luabridge::Stack<const char*>::get(lua, 3);
|
||||
|
||||
int args_n = (int)lua_strlen(lua, 3);
|
||||
|
||||
vector<boost::any> args;
|
||||
|
||||
for (int i = 4; i < args_n + 4; i++)
|
||||
{
|
||||
switch (types[i - 4])
|
||||
{
|
||||
case 'i':
|
||||
{
|
||||
args.emplace_back(luabridge::Stack<unsigned int>::get(lua, i));
|
||||
break;
|
||||
}
|
||||
|
||||
case 'q':
|
||||
{
|
||||
args.emplace_back(luabridge::Stack<signed int>::get(lua, i));
|
||||
break;
|
||||
}
|
||||
|
||||
/*case 'l':
|
||||
{
|
||||
args.emplace_back(luabridge::Stack<unsigned long long>::get(lua, i));
|
||||
break;
|
||||
}
|
||||
|
||||
case 'w':
|
||||
{
|
||||
args.emplace_back(luabridge::Stack<signed long long>::get(lua, i));
|
||||
break;
|
||||
}*/
|
||||
|
||||
case 'f':
|
||||
{
|
||||
args.emplace_back(luabridge::Stack<double>::get(lua, i));
|
||||
break;
|
||||
}
|
||||
|
||||
case 's':
|
||||
{
|
||||
args.emplace_back(luabridge::Stack<const char*>::get(lua, i));
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
stringstream ssErr;
|
||||
ssErr << "Lua: Unknown argument identifier" << "\"" << types[i] << "\"" << endl;
|
||||
throw std::runtime_error(ssErr.str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int id = mwmp::TimerAPI::CreateTimerLua(lua, callback, msec, types, args);
|
||||
luabridge::push(lua, id);
|
||||
return 1;
|
||||
}
|
@ -1,102 +0,0 @@
|
||||
//
|
||||
// Created by koncord on 09.05.16.
|
||||
//
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
#include <stdexcept>
|
||||
#include "LangNative.hpp"
|
||||
#include <Script/SystemInterface.hpp>
|
||||
#include <Script/Script.hpp>
|
||||
|
||||
using namespace std;
|
||||
|
||||
template<typename R>
|
||||
bool SetScript(lib_t lib, const char *name, R value)
|
||||
{
|
||||
SystemInterface<R *> result(lib, name);
|
||||
|
||||
if (result)
|
||||
*result.result = value;
|
||||
|
||||
return result.operator bool();
|
||||
}
|
||||
|
||||
void LangNative::LoadProgram(const char *filename)
|
||||
{
|
||||
FILE *file = fopen(filename, "rb");
|
||||
|
||||
if (!file)
|
||||
throw runtime_error("Script not found: " + string(filename));
|
||||
|
||||
fclose(file);
|
||||
|
||||
#ifdef _WIN32
|
||||
lib = LoadLibrary(filename);
|
||||
#else
|
||||
lib = dlopen(filename, RTLD_LAZY);
|
||||
#endif
|
||||
|
||||
if (!lib)
|
||||
throw runtime_error("Was not able to load C++ script: " + string(filename));
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
const char *prefix = SystemInterface<const char *>(lib, "prefix").result;
|
||||
string pf(prefix);
|
||||
|
||||
for (const auto &function : ScriptFunctions::functions)
|
||||
if (!SetScript(lib, string(pf + function.name).c_str(), function.func.addr))
|
||||
LOG_MESSAGE_SIMPLE(Log::LOG_WARN, "Script function pointer not found: %s", function.name);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
FreeProgram();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
int LangNative::FreeProgram()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
FreeLibrary(lib);
|
||||
#else
|
||||
dlclose(lib);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool LangNative::IsCallbackPresent(const char *name)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
boost::any LangNative::Call(const char *name, const char *argl, int buf, ...)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
boost::any LangNative::Call(const char *name, const char *argl, const std::vector<boost::any> &args)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
lib_t LangNative::GetInterface()
|
||||
{
|
||||
return lib;
|
||||
}
|
||||
|
||||
|
||||
LangNative::LangNative()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
LangNative::~LangNative()
|
||||
{
|
||||
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
//
|
||||
// Created by koncord on 09.05.16.
|
||||
//
|
||||
|
||||
#ifndef PLUGINSYSTEM3_LANGNATIVE_HPP
|
||||
#define PLUGINSYSTEM3_LANGNATIVE_HPP
|
||||
|
||||
|
||||
#include <Script/Language.hpp>
|
||||
#include <Script/SystemInterface.hpp>
|
||||
|
||||
class LangNative : public Language
|
||||
{
|
||||
lib_t lib;
|
||||
public:
|
||||
virtual lib_t GetInterface() override;
|
||||
LangNative();
|
||||
~LangNative();
|
||||
virtual void LoadProgram(const char *filename) override;
|
||||
virtual int FreeProgram() override;
|
||||
virtual bool IsCallbackPresent(const char *name) override;
|
||||
virtual boost::any Call(const char *name, const char *argl, int buf, ...) override;
|
||||
virtual boost::any Call(const char *name, const char *argl, const std::vector<boost::any> &args) override;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif //PLUGINSYSTEM3_LANGNATIVE_HPP
|
@ -1,458 +0,0 @@
|
||||
//
|
||||
// Created by koncord on 08.05.16.
|
||||
//
|
||||
|
||||
#include "LangPAWN.hpp"
|
||||
|
||||
|
||||
#include <amxmodules.h>
|
||||
#include <amxaux.h>
|
||||
#include "Script.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
typedef long NetworkID;
|
||||
|
||||
static vector<vector<char>> strings;
|
||||
static vector<pair<cell*, double>> floats;
|
||||
static pair<cell*, NetworkID*> data = {nullptr, nullptr};
|
||||
|
||||
void free_strings() noexcept {
|
||||
strings.clear();
|
||||
}
|
||||
|
||||
void free_floats() noexcept {
|
||||
for (const auto& value : floats)
|
||||
*value.first = amx_ftoc(value.second);
|
||||
|
||||
floats.clear();
|
||||
}
|
||||
|
||||
void free_data(unsigned int size) noexcept {
|
||||
if (data.first && data.second)
|
||||
for (unsigned int i = 0; i < size; ++i)
|
||||
data.first[i] = data.second[i];
|
||||
|
||||
data.first = nullptr;
|
||||
data.second = nullptr;
|
||||
}
|
||||
|
||||
void after_call() noexcept {
|
||||
free_strings();
|
||||
free_floats();
|
||||
}
|
||||
|
||||
template<typename R>
|
||||
void after_call(const R&) noexcept {
|
||||
free_strings();
|
||||
free_floats();
|
||||
}
|
||||
|
||||
template<>
|
||||
void after_call(const unsigned int& result) noexcept {
|
||||
free_strings();
|
||||
free_floats();
|
||||
free_data(result);
|
||||
}
|
||||
|
||||
template<typename R, unsigned int I, unsigned int F>
|
||||
struct PAWN_extract_ {
|
||||
inline static R PAWN_extract(AMX*&&, const cell*&& params) noexcept {
|
||||
return static_cast<R>(forward<const cell*>(params)[I]);
|
||||
}
|
||||
};
|
||||
|
||||
template<unsigned int I, unsigned int F>
|
||||
struct PAWN_extract_<void*, I, F>
|
||||
{
|
||||
inline static void* PAWN_extract(AMX *&&amx, const cell *&¶ms) noexcept
|
||||
{
|
||||
return amx_Address(amx, forward<const cell *>(params)[I]); // fixme: I'm not sure in this fix
|
||||
}
|
||||
};
|
||||
|
||||
template<unsigned int I, unsigned int F>
|
||||
struct PAWN_extract_<double, I, F> {
|
||||
inline static double PAWN_extract(AMX*&&, const cell*&& params) noexcept {
|
||||
return amx_ctof(forward<const cell*>(params)[I]);
|
||||
}
|
||||
};
|
||||
|
||||
template<unsigned int I, unsigned int F>
|
||||
struct PAWN_extract_<const char*, I, F> {
|
||||
inline static const char* PAWN_extract(AMX*&& amx, const cell*&& params) noexcept {
|
||||
int len;
|
||||
cell* source;
|
||||
|
||||
source = amx_Address(amx, params[I]);
|
||||
amx_StrLen(source, &len);
|
||||
|
||||
strings.emplace_back(len + 1);
|
||||
char* value = &strings.back()[0];
|
||||
amx_GetString(value, source, 0, UNLIMITED);
|
||||
|
||||
return value;
|
||||
}
|
||||
};
|
||||
|
||||
template<unsigned int I, unsigned int F>
|
||||
struct PAWN_extract_<double*, I, F> {
|
||||
inline static double* PAWN_extract(AMX*&& amx, const cell*&& params) noexcept {
|
||||
floats.emplace_back(amx_Address(amx, params[I]), 0.00);
|
||||
return &floats.back().second;
|
||||
}
|
||||
};
|
||||
|
||||
template<unsigned int I, unsigned int F>
|
||||
struct PAWN_extract_<NetworkID**, I, F> {
|
||||
inline static NetworkID** PAWN_extract(AMX*&& amx, const cell*&& params) noexcept {
|
||||
constexpr ScriptFunctionData const& F_ = ScriptFunctions::functions[F];
|
||||
static_assert(F_.func.numargs == I, "NetworkID** must be the last parameter");
|
||||
data.first = amx_Address(amx, params[I]);
|
||||
return &data.second;
|
||||
}
|
||||
};
|
||||
|
||||
template<unsigned int I, unsigned int F>
|
||||
struct PAWN_dispatch_ {
|
||||
template<typename R, typename... Args>
|
||||
inline static R PAWN_dispatch(AMX*&& amx, const cell*&& params, Args&&... args) noexcept {
|
||||
constexpr ScriptFunctionData const& F_ = ScriptFunctions::functions[F];
|
||||
auto arg = PAWN_extract_<typename CharType<F_.func.types[I - 1]>::type, I, F>::PAWN_extract(forward<AMX*>(amx), forward<const cell*>(params));
|
||||
return PAWN_dispatch_<I - 1, F>::template PAWN_dispatch<R>(
|
||||
forward<AMX*>(amx),
|
||||
forward<const cell*>(params),
|
||||
arg,
|
||||
forward<Args>(args)...);
|
||||
}
|
||||
};
|
||||
|
||||
template<unsigned int F>
|
||||
struct PAWN_dispatch_<0, F> {
|
||||
template<typename R, typename... Args>
|
||||
inline static R PAWN_dispatch(AMX*&&, const cell*&&, Args&&... args) noexcept {
|
||||
constexpr ScriptFunctionData const& F_ = ScriptFunctions::functions[F];
|
||||
return reinterpret_cast<FunctionEllipsis<R>>(F_.func.addr)(forward<Args>(args)...);
|
||||
}
|
||||
};
|
||||
|
||||
template<unsigned int I>
|
||||
static typename enable_if<ScriptFunctions::functions[I].func.ret == 'v', cell>::type wrapper(AMX* amx, const cell* params) noexcept {
|
||||
PAWN_dispatch_<ScriptFunctions::functions[I].func.numargs, I>::template PAWN_dispatch<void>(forward<AMX*>(amx), forward<const cell*>(params));
|
||||
after_call();
|
||||
return 1;
|
||||
}
|
||||
|
||||
template<unsigned int I>
|
||||
static typename enable_if<ScriptFunctions::functions[I].func.ret == 'f', cell>::type wrapper(AMX* amx, const cell* params) noexcept {
|
||||
double value = PAWN_dispatch_<ScriptFunctions::functions[I].func.numargs, I>::template PAWN_dispatch<double>(forward<AMX*>(amx), forward<const cell*>(params));
|
||||
after_call();
|
||||
return amx_ftoc(value);
|
||||
}
|
||||
|
||||
template<unsigned int I>
|
||||
static typename enable_if<ScriptFunctions::functions[I].func.ret == 's', cell>::type wrapper(AMX* amx, const cell* params) noexcept {
|
||||
const char* value = PAWN_dispatch_<ScriptFunctions::functions[I].func.numargs, I>::template PAWN_dispatch<const char*>(forward<AMX*>(amx), forward<const cell*>(params));
|
||||
after_call();
|
||||
|
||||
if (value) {
|
||||
cell* dest = amx_Address(amx, params[ScriptFunctions::functions[I].func.numargs + 1]);
|
||||
amx_SetString(dest, value, 1, 0, strlen(value) + 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<unsigned int I>
|
||||
static typename enable_if<ScriptFunctions::functions[I].func.ret != 'v' && ScriptFunctions::functions[I].func.ret != 'f' && ScriptFunctions::functions[I].func.ret != 's', cell>::type wrapper(AMX* amx, const cell* params) noexcept {
|
||||
auto result = PAWN_dispatch_<ScriptFunctions::functions[I].func.numargs, I>::template PAWN_dispatch<typename CharType<ScriptFunctions::functions[I].func.ret>::type>(forward<AMX*>(amx), forward<const cell*>(params));
|
||||
after_call(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
template<unsigned int I> struct F_ { static constexpr AMX_NATIVE_INFO F{ScriptFunctions::functions[I].name, wrapper<I>}; };
|
||||
template<> struct F_<0> { static constexpr AMX_NATIVE_INFO F{"CreateTimer", LangPAWN::CreateTimer}; };
|
||||
template<> struct F_<1> { static constexpr AMX_NATIVE_INFO F{"CreateTimerEx", LangPAWN::CreateTimerEx}; };
|
||||
template<> struct F_<2> { static constexpr AMX_NATIVE_INFO F{"MakePublic", LangPAWN::MakePublic}; };
|
||||
template<> struct F_<3> { static constexpr AMX_NATIVE_INFO F{"CallPublic", LangPAWN::CallPublic}; };
|
||||
|
||||
void LangPAWN::LoadProgram(const char *filename)
|
||||
{
|
||||
int err = aux_LoadProgram(amx, filename, 0);
|
||||
if (err != AMX_ERR_NONE)
|
||||
throw runtime_error("PAWN script " + string(filename) + " error (" + to_string(err) + "): \"" + string(aux_StrError(err)) + "\"");
|
||||
|
||||
amx_CoreInit(amx);
|
||||
amx_ConsoleInit(amx);
|
||||
amx_FloatInit(amx);
|
||||
amx_TimeInit(amx);
|
||||
amx_StringInit(amx);
|
||||
amx_FileInit(amx);
|
||||
|
||||
constexpr auto functions_n = sizeof(ScriptFunctions::functions) / sizeof(ScriptFunctions::functions[0]);
|
||||
|
||||
amx_Register(amx, functions(IndicesFor<functions_n>{}), functions_n); // TODO: throw if error
|
||||
|
||||
}
|
||||
|
||||
int LangPAWN::FreeProgram()
|
||||
{
|
||||
int err = aux_FreeProgram(amx);
|
||||
delete amx;
|
||||
return err;
|
||||
}
|
||||
|
||||
bool LangPAWN::IsCallbackPresent(const char *name)
|
||||
{
|
||||
int idx;
|
||||
return (amx_FindPublic(amx, name, &idx) == AMX_ERR_NONE);
|
||||
}
|
||||
|
||||
boost::any LangPAWN::Call(const char *name, const char *argl, int buf, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, buf);
|
||||
cell ret = 0;
|
||||
vector<pair<cell *, char *>> strings;
|
||||
|
||||
try
|
||||
{
|
||||
int idx = 0;
|
||||
int err = 0;
|
||||
|
||||
err = amx_FindPublic(amx, name, &idx);
|
||||
|
||||
if (err != AMX_ERR_NONE)
|
||||
throw runtime_error("PAWN runtime error (" + to_string(err) + "): \"" + string(aux_StrError(err)) + "\".");
|
||||
|
||||
unsigned int len = strlen(argl);
|
||||
vector<cell> args_amx;
|
||||
|
||||
for (unsigned int i = 0; i < len; ++i)
|
||||
{
|
||||
switch (argl[i])
|
||||
{
|
||||
case 'i':
|
||||
args_amx.emplace_back(va_arg(args, unsigned
|
||||
int));
|
||||
break;
|
||||
|
||||
case 'q':
|
||||
args_amx.emplace_back(va_arg(args, signed
|
||||
int));
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
args_amx.emplace_back(va_arg(args, unsigned
|
||||
long
|
||||
long));
|
||||
break;
|
||||
|
||||
case 'w':
|
||||
args_amx.emplace_back(va_arg(args, signed
|
||||
long
|
||||
long));
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
{
|
||||
double value = va_arg(args, double);
|
||||
args_amx.emplace_back(amx_ftoc(value));
|
||||
break;
|
||||
}
|
||||
|
||||
case 'p':
|
||||
args_amx.emplace_back(reinterpret_cast<uintptr_t>(va_arg(args, void*)));
|
||||
break;
|
||||
|
||||
case 's':
|
||||
args_amx.emplace_back(reinterpret_cast<uintptr_t>(va_arg(args, char*)));
|
||||
break;
|
||||
|
||||
default:
|
||||
throw runtime_error("PAWN call: Unknown argument identifier " + argl[i]);
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned int i = len; i; --i)
|
||||
{
|
||||
switch (argl[i - 1])
|
||||
{
|
||||
case 's':
|
||||
{
|
||||
char *string = reinterpret_cast<char *>(static_cast<unsigned int>(args_amx[i - 1]));
|
||||
cell *store;
|
||||
amx_PushString(amx, &store, string, 1, 0);
|
||||
strings.emplace_back(store, string);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
amx_Push(amx, args_amx[i - 1]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
err = amx_Exec(amx, &ret, idx);
|
||||
|
||||
if (err != AMX_ERR_NONE)
|
||||
throw runtime_error("PAWN runtime error (" + to_string(err) + "): \"" + string(aux_StrError(err)) + "\".");
|
||||
|
||||
if (buf != 0)
|
||||
for (const auto &str : strings)
|
||||
amx_GetString(str.second, str.first, 0, strlen(str.second) + 1);
|
||||
|
||||
if (!strings.empty())
|
||||
amx_Release(amx, strings[0].first);
|
||||
}
|
||||
|
||||
catch (...)
|
||||
{
|
||||
va_end(args);
|
||||
|
||||
if (!strings.empty())
|
||||
amx_Release(amx, strings[0].first);
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
return boost::any(ret);
|
||||
}
|
||||
|
||||
boost::any LangPAWN::Call(const char *name, const char *argl, const std::vector<boost::any> &args)
|
||||
{
|
||||
cell ret = 0;
|
||||
cell *str = nullptr;
|
||||
|
||||
try
|
||||
{
|
||||
int idx = 0;
|
||||
int err = 0;
|
||||
|
||||
err = amx_FindPublic(amx, name, &idx);
|
||||
|
||||
if (err != AMX_ERR_NONE)
|
||||
throw runtime_error("PAWN runtime error (" + to_string(err) + "): \"" + string(aux_StrError(err)) + "\".");
|
||||
|
||||
for (intptr_t i = strlen(argl) - 1; i >= 0; i--)
|
||||
{
|
||||
switch (argl[i])
|
||||
{
|
||||
case 'i':
|
||||
{
|
||||
cell value = (cell) boost::any_cast<unsigned int>(args.at(i));
|
||||
amx_Push(amx, value);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'q':
|
||||
{
|
||||
cell value = (cell) boost::any_cast<signed int>(args.at(i));
|
||||
amx_Push(amx, value);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'l':
|
||||
{
|
||||
cell value = (cell) boost::any_cast<unsigned long long>(args.at(i));
|
||||
amx_Push(amx, value);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'w':
|
||||
{
|
||||
cell value = (cell) boost::any_cast<signed long long>(args.at(i));
|
||||
amx_Push(amx, value);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'f':
|
||||
{
|
||||
double value = boost::any_cast<double>(args.at(i));
|
||||
amx_Push(amx, amx_ftoc(value));
|
||||
break;
|
||||
}
|
||||
|
||||
case 'p':
|
||||
{
|
||||
cell value = (cell) boost::any_cast<void *>(args.at(i));
|
||||
amx_Push(amx, value);
|
||||
break;
|
||||
}
|
||||
|
||||
case 's':
|
||||
{
|
||||
string string_ = boost::any_cast<string>(args.at(i));
|
||||
cell *store;
|
||||
amx_PushString(amx, &store, string_.c_str(), 1, 0);
|
||||
|
||||
if (!str)
|
||||
str = store;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
throw runtime_error("PAWN call: Unknown argument identifier " + argl[i]);
|
||||
}
|
||||
}
|
||||
|
||||
err = amx_Exec(amx, &ret, idx);
|
||||
|
||||
if (err != AMX_ERR_NONE)
|
||||
throw runtime_error("PAWN runtime error (" + to_string(err) + "): \"" + string(aux_StrError(err)) + "\".");
|
||||
|
||||
if (str)
|
||||
amx_Release(amx, str);
|
||||
}
|
||||
|
||||
catch (...)
|
||||
{
|
||||
if (str)
|
||||
amx_Release(amx, str);
|
||||
|
||||
throw;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<size_t... Indices>
|
||||
inline AMX_NATIVE_INFO *LangPAWN::functions(indices<Indices...>)
|
||||
{
|
||||
|
||||
static AMX_NATIVE_INFO functions_[sizeof...(Indices)]{
|
||||
F_<Indices>::F...
|
||||
};
|
||||
|
||||
static_assert(
|
||||
sizeof(functions_) / sizeof(functions_[0]) == sizeof(ScriptFunctions::functions) / sizeof(ScriptFunctions::functions[0]),
|
||||
"Not all functions have been mapped to PAWN");
|
||||
|
||||
return functions_;
|
||||
}
|
||||
|
||||
|
||||
lib_t LangPAWN::GetInterface()
|
||||
{
|
||||
return reinterpret_cast<lib_t>(amx);
|
||||
}
|
||||
|
||||
LangPAWN::LangPAWN()
|
||||
{
|
||||
//throw std::runtime_error("Pawn is no longer supported, use Terra/Lua!");
|
||||
amx = new AMX();
|
||||
}
|
||||
|
||||
|
||||
LangPAWN::LangPAWN(AMX *amx)
|
||||
{
|
||||
this->amx = amx;
|
||||
}
|
||||
|
||||
|
||||
LangPAWN::~LangPAWN()
|
||||
{
|
||||
|
||||
}
|
@ -1,46 +0,0 @@
|
||||
//
|
||||
// Created by koncord on 08.05.16.
|
||||
//
|
||||
|
||||
#ifndef PLUGINSYSTEM3_LANGPAWN_HPP
|
||||
#define PLUGINSYSTEM3_LANGPAWN_HPP
|
||||
|
||||
#include "Language.hpp"
|
||||
#include <amx.h>
|
||||
|
||||
class LangPAWN: public Language
|
||||
{
|
||||
private:
|
||||
template<std::size_t... Is>
|
||||
struct indices {};
|
||||
template<std::size_t N, std::size_t... Is>
|
||||
struct build_indices : build_indices<N-1, N-1, Is...> {};
|
||||
template<std::size_t... Is>
|
||||
struct build_indices<0, Is...> : indices<Is...> {};
|
||||
template<std::size_t N>
|
||||
using IndicesFor = build_indices<N>;
|
||||
|
||||
public:
|
||||
virtual lib_t GetInterface() override;
|
||||
template<std::size_t... Indices>
|
||||
static AMX_NATIVE_INFO* functions(indices<Indices...>);
|
||||
|
||||
AMX *amx;
|
||||
public:
|
||||
LangPAWN();
|
||||
LangPAWN(AMX *amx);
|
||||
~LangPAWN();
|
||||
static cell MakePublic(AMX *amx, const cell *params) noexcept;
|
||||
static cell CallPublic(AMX *amx, const cell *params) noexcept;
|
||||
static cell CreateTimer(AMX *amx, const cell *params) noexcept;
|
||||
static cell CreateTimerEx(AMX *amx, const cell *params) noexcept;
|
||||
|
||||
virtual void LoadProgram(const char *filename) override;
|
||||
virtual int FreeProgram() override;
|
||||
virtual bool IsCallbackPresent(const char *name) override;
|
||||
virtual boost::any Call(const char *name, const char *argl, int buf, ...) override;
|
||||
virtual boost::any Call(const char *name, const char *argl, const std::vector<boost::any> &args) override;
|
||||
};
|
||||
|
||||
|
||||
#endif //PLUGINSYSTEM3_LANGPAWN_HPP
|
@ -1,154 +0,0 @@
|
||||
//
|
||||
// Created by koncord on 09.05.16.
|
||||
//
|
||||
|
||||
#include <API/PublicFnAPI.hpp>
|
||||
#include "LangPAWN.hpp"
|
||||
#include "API/TimerAPI.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
cell LangPAWN::MakePublic(AMX *amx, const cell *params) noexcept
|
||||
{
|
||||
int len;
|
||||
cell* source;
|
||||
|
||||
source = amx_Address(amx, params[1]);
|
||||
amx_StrLen(source, &len);
|
||||
vector<char> real;
|
||||
real.reserve(len + 1);
|
||||
|
||||
amx_GetString(&real[0], source, 0, UNLIMITED);
|
||||
|
||||
source = amx_Address(amx, params[2]);
|
||||
amx_StrLen(source, &len);
|
||||
vector<char> name;
|
||||
name.reserve(len + 1);
|
||||
|
||||
amx_GetString(&name[0], source, 0, UNLIMITED);
|
||||
|
||||
cell *ret_addr = amx_Address(amx, params[3]);
|
||||
char ret_type = static_cast<char>(*reinterpret_cast<cell*>(&ret_addr));
|
||||
|
||||
source = amx_Address(amx, params[4]);
|
||||
amx_StrLen(source, &len);
|
||||
vector<char> def;
|
||||
def.reserve(len + 1);
|
||||
|
||||
amx_GetString(&def[0], source, 0, UNLIMITED);
|
||||
|
||||
|
||||
|
||||
Public::MakePublic(&real[0], amx, &name[0], ret_type, &def[0]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
cell LangPAWN::CallPublic(AMX *amx, const cell *params) noexcept
|
||||
{
|
||||
int len;
|
||||
cell* source;
|
||||
|
||||
source = amx_Address(amx, params[1]);
|
||||
amx_StrLen(source, &len);
|
||||
vector<char> name;
|
||||
name.reserve(len + 1);
|
||||
|
||||
amx_GetString(&name[0], source, 0, UNLIMITED);
|
||||
|
||||
string def;
|
||||
|
||||
try
|
||||
{
|
||||
def = Public::GetDefinition(&name[0]);
|
||||
}
|
||||
catch (...) { return 0; }
|
||||
|
||||
vector<boost::any> args;
|
||||
unsigned int count = (params[0] / sizeof(cell)) - 1;
|
||||
|
||||
if (count != def.length())
|
||||
throw runtime_error("Script call: Number of arguments does not match definition");
|
||||
|
||||
for (unsigned int i = 0; i < count; ++i)
|
||||
{
|
||||
cell* data = amx_Address(amx, params[i + 2]);
|
||||
|
||||
switch (def[i])
|
||||
{
|
||||
case 'i':
|
||||
{
|
||||
args.emplace_back((unsigned int) *data);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'q':
|
||||
{
|
||||
args.emplace_back((signed int) *data);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'l':
|
||||
{
|
||||
args.emplace_back((unsigned long long) *data);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'w':
|
||||
{
|
||||
args.emplace_back((signed long long) *data);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'f':
|
||||
{
|
||||
args.emplace_back((double) amx_ctof(*data));
|
||||
break;
|
||||
}
|
||||
|
||||
case 'p':
|
||||
{
|
||||
args.emplace_back((void*) data);
|
||||
break;
|
||||
}
|
||||
|
||||
case 's':
|
||||
{
|
||||
amx_StrLen(data, &len);
|
||||
vector<char> str;
|
||||
str.reserve(len + 1);
|
||||
amx_GetString(&str[0], data, 0, UNLIMITED);
|
||||
args.emplace_back(string(&str[0]).c_str());
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
throw runtime_error("PAWN call: Unknown argument identifier " + def[i]);
|
||||
}
|
||||
}
|
||||
|
||||
boost::any result = Public::Call(&name[0], args);
|
||||
if (result.empty())
|
||||
return 0;
|
||||
|
||||
cell ret = 0;
|
||||
|
||||
if (result.type().hash_code() == typeid(signed int).hash_code())
|
||||
ret = boost::any_cast<signed int>(result);
|
||||
else if (result.type().hash_code() == typeid(unsigned int).hash_code())
|
||||
ret = boost::any_cast<unsigned int>(result);
|
||||
else if (result.type().hash_code() == typeid(double).hash_code())
|
||||
ret = amx_ftoc(result);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
cell LangPAWN::CreateTimer(AMX *amx, const cell *params) noexcept
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
cell LangPAWN::CreateTimerEx(AMX *amx, const cell *params) noexcept
|
||||
{
|
||||
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
//
|
||||
// Created by koncord on 19.03.16.
|
||||
//
|
||||
|
||||
#ifndef PLUGINSYSTEM3_LANGUAGE_HPP
|
||||
#define PLUGINSYSTEM3_LANGUAGE_HPP
|
||||
|
||||
#include "Types.hpp"
|
||||
|
||||
#include <boost/any.hpp>
|
||||
#include <vector>
|
||||
|
||||
class Language
|
||||
{
|
||||
public:
|
||||
virtual ~Language(){}
|
||||
virtual void LoadProgram(const char* filename) = 0;
|
||||
virtual int FreeProgram() = 0;
|
||||
virtual bool IsCallbackPresent(const char* name) = 0;
|
||||
virtual boost::any Call(const char* name, const char* argl, int buf, ...) = 0;
|
||||
virtual boost::any Call(const char* name, const char* argl, const std::vector<boost::any>& args) = 0;
|
||||
|
||||
virtual lib_t GetInterface() = 0;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif //PLUGINSYSTEM3_LANGUAGE_HPP
|
@ -0,0 +1,429 @@
|
||||
//
|
||||
// Created by koncord on 01.08.17.
|
||||
//
|
||||
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/tokenizer.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <components/misc/stringops.hpp>
|
||||
#include <apps/openmw/mwworld/inventorystore.hpp>
|
||||
#include <apps/openmw-mp/Networking.hpp>
|
||||
#include <components/openmw-mp/Version.hpp>
|
||||
#include <apps/openmw-mp/GUI.hpp>
|
||||
#include <apps/openmw-mp/Dialogue.hpp>
|
||||
#include <apps/openmw-mp/Factions.hpp>
|
||||
#include <apps/openmw-mp/Quests.hpp>
|
||||
#include <apps/openmw-mp/Spells.hpp>
|
||||
#include <components/openmw-mp/NetworkMessages.hpp>
|
||||
#include "LuaState.hpp"
|
||||
#include "EventController.hpp"
|
||||
#include "luaUtils.hpp"
|
||||
#include "CommandController.hpp"
|
||||
#include "../Inventory.hpp"
|
||||
#include "../Settings.hpp"
|
||||
#include "../Players.hpp"
|
||||
#include "../Networking.hpp"
|
||||
#include "../MasterClient.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
LuaState::LuaState()
|
||||
{
|
||||
lua = make_shared<sol::state>();
|
||||
lua->open_libraries();
|
||||
LuaUtils::Init(*this);
|
||||
|
||||
actorCtrl = make_unique<ActorController>();
|
||||
ActorController::Init(*this);
|
||||
|
||||
eventCtrl = make_unique<EventController>(this);
|
||||
EventController::Init(*this);
|
||||
|
||||
objectCtrl = make_unique<ObjectController>();
|
||||
ObjectController::Init(*this);
|
||||
|
||||
cmdCtrl = make_unique<CommandController>();
|
||||
Player::Init(*this);
|
||||
CharClass::Init(*this);
|
||||
Inventory::Init(*this);
|
||||
GameSettings::Init(*this);
|
||||
Books::Init(*this);
|
||||
GUI::Init(*this);
|
||||
Dialogue::Init(*this);
|
||||
Factions::Init(*this);
|
||||
Faction::Init(*this);
|
||||
JournalItem::Init(*this);
|
||||
Quests::Init(*this);
|
||||
Effect::Init(*this);
|
||||
Spell::Init(*this);
|
||||
Spells::Init(*this);
|
||||
|
||||
Players::Init(*this);
|
||||
|
||||
timerCtrl = make_unique<TimerController>();
|
||||
TimerController::Init(*this);
|
||||
Timer::Init(*this);
|
||||
|
||||
CommandController::Init(*this);
|
||||
|
||||
dataEnv = sol::environment(*lua, sol::create, lua->globals());
|
||||
lua->set("Data", dataEnv); // plain global environment for communicating between mods
|
||||
auto coreTable = dataEnv.create("Core");
|
||||
coreTable["VERSION"] = TES3MP_VERSION;
|
||||
coreTable["PROTOCOL"] = TES3MP_PROTO_VERSION;
|
||||
coreTable["loadedMods"] = coreTable.create();
|
||||
|
||||
// errors in sol::functions catches only in debug build for better performance
|
||||
#ifdef SOL_SAFE_FUNCTIONS
|
||||
lua->set_function("ErrorHandler", [](sol::object error_msg) {
|
||||
LOG_MESSAGE_SIMPLE(Log::LOG_ERROR, ("Lua: " + error_msg.as<string>()).c_str());
|
||||
});
|
||||
|
||||
sol::reference errHandler = (*lua)["ErrorHandler"];
|
||||
sol::protected_function::set_default_handler(errHandler);
|
||||
#endif
|
||||
|
||||
sol::table Constants = lua->create_named_table("Constants");
|
||||
|
||||
Constants.set_function("GetAttributeCount", []() {
|
||||
return ESM::Attribute::Length;
|
||||
});
|
||||
|
||||
Constants.set_function("GetSkillCount", []() {
|
||||
return ESM::Skill::Length;
|
||||
});
|
||||
|
||||
Constants.set_function("GetAttributeId", [](const string &name) {
|
||||
for (int x = 0; x < ESM::Attribute::Length; x++)
|
||||
if (Misc::StringUtils::ciEqual(name, ESM::Attribute::sAttributeNames[x]))
|
||||
return x;
|
||||
return -1;
|
||||
});
|
||||
|
||||
Constants.set_function("GetSkillId", [](const string &name) {
|
||||
for (int x = 0; x < ESM::Skill::Length; x++)
|
||||
if (Misc::StringUtils::ciEqual(name, ESM::Skill::sSkillNames[x]))
|
||||
return x;
|
||||
return -1;
|
||||
});
|
||||
|
||||
Constants.set_function("GetAttributeName", [](unsigned short attribute) -> const string {
|
||||
if (attribute >= ESM::Attribute::Length)
|
||||
return "invalid";
|
||||
|
||||
return ESM::Attribute::sAttributeNames[attribute];
|
||||
});
|
||||
|
||||
Constants.set_function("GetSkillName", [](unsigned short skill) -> const string {
|
||||
if (skill >= ESM::Skill::Length)
|
||||
return "invalid";
|
||||
|
||||
return ESM::Skill::sSkillNames[skill];
|
||||
});
|
||||
|
||||
Constants.set_function("GetEquipmentSize", []() {
|
||||
return MWWorld::InventoryStore::Slots;
|
||||
});
|
||||
|
||||
|
||||
lua->set_function("getCurrentMpNum", []() {
|
||||
return mwmp::Networking::getPtr()->getCurrentMpNum();
|
||||
});
|
||||
lua->set_function("setCurrentMpNum", [](int num) {
|
||||
mwmp::Networking::getPtr()->setCurrentMpNum(num);
|
||||
});
|
||||
|
||||
lua->set_function("logMessage", [](unsigned short level, const char *message) {
|
||||
LOG_MESSAGE_SIMPLE(level, "[Script]: %s", message);
|
||||
});
|
||||
lua->set_function("logAppend", [](unsigned short level, const char *message) {
|
||||
LOG_APPEND(level, "[Script]: %s", message);
|
||||
});
|
||||
|
||||
lua->set_function("stopServer", [](int code) {
|
||||
mwmp::Networking::getPtr()->stopServer(code);
|
||||
});
|
||||
|
||||
lua->set_function("banAddress", [](const char *ipAddress) {
|
||||
mwmp::Networking::getPtr()->banAddress(ipAddress);
|
||||
});
|
||||
|
||||
lua->set_function("unbanAddress", [](const char *ipAddress) {
|
||||
mwmp::Networking::getPtr()->unbanAddress(ipAddress);
|
||||
});
|
||||
|
||||
lua->set_function("setRuleValue", [](const std::string &key, sol::object value) {
|
||||
if (!value.valid())
|
||||
return;
|
||||
|
||||
auto mc = mwmp::Networking::getPtr()->getMasterClient();
|
||||
if (mc)
|
||||
{
|
||||
sol::type type = value.get_type();
|
||||
if (type == sol::type::string)
|
||||
mc->SetRuleString(key, value.as<string>());
|
||||
if (type == sol::type::number)
|
||||
mc->SetRuleValue(key, value.as<double>());
|
||||
}
|
||||
});
|
||||
|
||||
lua->set_function("setModname", [](const std::string &modname) {
|
||||
auto mc = mwmp::Networking::getPtr()->getMasterClient();
|
||||
if (mc)
|
||||
mc->SetModname(modname);
|
||||
});
|
||||
|
||||
lua->set_function("setHostname", [](const std::string &hostname) {
|
||||
auto mc = mwmp::Networking::getPtr()->getMasterClient();
|
||||
if (mc)
|
||||
mc->SetHostname(hostname);
|
||||
});
|
||||
|
||||
lua->set_function("setServerPassword", [](const std::string &passw) {
|
||||
mwmp::Networking::getPtr()->setServerPassword(passw);
|
||||
});
|
||||
|
||||
lua->set_function("setHour", [](double hour) {
|
||||
auto packet = mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_GAME_TIME);
|
||||
Players::for_each([&hour, &packet](std::shared_ptr<Player> player){
|
||||
player->hour = hour;
|
||||
player->month = -1;
|
||||
player->day = -1;
|
||||
|
||||
packet->setPlayer(player.get());
|
||||
packet->Send(false);
|
||||
});
|
||||
});
|
||||
|
||||
lua->set_function("setMonth", [](int month) {
|
||||
|
||||
auto packet = mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_GAME_TIME);
|
||||
Players::for_each([&month, &packet](std::shared_ptr<Player> player){
|
||||
player->hour = -1;
|
||||
player->month = month;
|
||||
player->day = -1;
|
||||
|
||||
packet->setPlayer(player.get());
|
||||
packet->Send(false);
|
||||
});
|
||||
});
|
||||
|
||||
lua->set_function("setDay", [](int day) {
|
||||
auto packet = mwmp::Networking::get().getPlayerPacketController()->GetPacket(ID_GAME_TIME);
|
||||
Players::for_each([&day, &packet](std::shared_ptr<Player> player){
|
||||
player->hour = -1;
|
||||
player->month = -1;
|
||||
player->day = day;
|
||||
|
||||
packet->setPlayer(player.get());
|
||||
packet->Send(false);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
sol::environment LuaState::openScript(std::string path, std::string modname)
|
||||
{
|
||||
cout << "Loading file: " << path + "/" + modname + "/main.lua" << endl;
|
||||
sol::environment env(*lua, sol::create, lua->globals());
|
||||
std::string package_path = env["package"]["path"];
|
||||
env["package"]["path"] = Utils::convertPath(path + "/" + modname + "/?.lua") + ";" + package_path;
|
||||
package_path = env["package"]["path"];
|
||||
//env["ModInfo"] = sol::create;
|
||||
|
||||
lua->script_file(path + "/" + modname + "/main.lua", env);
|
||||
|
||||
sol::table modinfo = env["ModInfo"];
|
||||
if (!modinfo.valid())
|
||||
throw runtime_error("ModInfo table for \"" + modname + "\" not found");
|
||||
|
||||
if (modinfo["name"].get_type() != sol::type::string)
|
||||
throw runtime_error(modname + R"(: ModInfo["name"] undefined or not string")");
|
||||
|
||||
if (modinfo["version"].get_type() != sol::type::string)
|
||||
throw runtime_error(modname + R"(: ModInfo["version"] undefined or not string")");
|
||||
|
||||
sol::table dependencies = modinfo["dependencies"];
|
||||
|
||||
if (dependencies.get_type() != sol::type::table)
|
||||
throw runtime_error(modname + R"(: ModInfo["dependencies"] undefined or not table")");
|
||||
|
||||
string name = env["ModInfo"]["name"];
|
||||
|
||||
mods.emplace(name, env);
|
||||
sol::table loaded = dataEnv["Core"]["loadedMods"];
|
||||
loaded.add(name);
|
||||
|
||||
cout << "modname: " << name << endl;
|
||||
|
||||
return env;
|
||||
}
|
||||
|
||||
void LuaState::addGlobalPackagePath(const std::string &path)
|
||||
{
|
||||
std::string package_path = (*lua)["package"]["path"];
|
||||
(*lua)["package"]["path"] = Utils::convertPath(path) + ";" + package_path;
|
||||
}
|
||||
|
||||
void LuaState::addGlobalCPath(const std::string &path)
|
||||
{
|
||||
std::string cpath = (*lua)["package"]["cpath"];
|
||||
(*lua)["package"]["cpath"] = Utils::convertPath(path) + ";" + cpath;
|
||||
}
|
||||
|
||||
CommandController &LuaState::getCmdCtrl()
|
||||
{
|
||||
return *cmdCtrl;
|
||||
}
|
||||
|
||||
EventController &LuaState::getEventCtrl()
|
||||
{
|
||||
return *eventCtrl;
|
||||
}
|
||||
|
||||
TimerController &LuaState::getTimerCtrl()
|
||||
{
|
||||
return *timerCtrl;
|
||||
}
|
||||
|
||||
ActorController &LuaState::getActorCtrl()
|
||||
{
|
||||
return *actorCtrl;
|
||||
}
|
||||
|
||||
ObjectController &LuaState::getObjectCtrl()
|
||||
{
|
||||
return *objectCtrl;
|
||||
}
|
||||
|
||||
int CompVersion(const string &wishVersion, const string &depVersionFound)
|
||||
{
|
||||
unsigned startVer = 0;
|
||||
|
||||
if (wishVersion[0] == '>')
|
||||
{
|
||||
startVer = 1;
|
||||
|
||||
if (wishVersion[1] == '=')
|
||||
startVer = 2;
|
||||
}
|
||||
|
||||
typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
|
||||
boost::char_separator<char> sep(".");
|
||||
tokenizer tokensWish(wishVersion.begin() + startVer, wishVersion.end(), sep), tokensFound(depVersionFound, sep);
|
||||
|
||||
auto wishIter = tokensWish.begin();
|
||||
auto founditer = tokensFound.begin();
|
||||
int bellowExpected = 0;
|
||||
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
auto v1 = boost::lexical_cast<int>(*(wishIter++));
|
||||
auto v2 = boost::lexical_cast<int>(*(founditer++));
|
||||
|
||||
if (v2 > v1 && startVer > 0)
|
||||
return 0; // found applicable version
|
||||
|
||||
if (v2 <= v1)
|
||||
{
|
||||
if (v2 == v1 && startVer == 1)
|
||||
bellowExpected++;
|
||||
else if (v2 < v1)
|
||||
return -1; // found version below expected
|
||||
continue;
|
||||
}
|
||||
|
||||
return 1; // version higher than expected
|
||||
}
|
||||
|
||||
if (bellowExpected == 3)
|
||||
return -1; // found version below expected
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void LuaState::loadMods()
|
||||
{
|
||||
using namespace boost::filesystem;
|
||||
|
||||
auto funcLoadMods = [this](path path) {
|
||||
path /= "mods";
|
||||
const auto mainScript = "main.lua";
|
||||
if (!is_directory(path))
|
||||
throw runtime_error(path.string() + ": No such directory.");
|
||||
for (const auto &modDir : directory_iterator(path))
|
||||
{
|
||||
if (is_directory(modDir.status()) && exists(modDir.path() / mainScript))
|
||||
openScript(path.string(), modDir.path().filename().string());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
const char* libExt = ".dll";
|
||||
#else
|
||||
const char* libExt = ".so";
|
||||
#endif
|
||||
|
||||
|
||||
path envServerDir = std::getenv("TES3MP_SERVER_DIR");
|
||||
const char *envServerUserDir = std::getenv("TES3MP_SERVER_USERDIR");
|
||||
|
||||
if (envServerDir.empty())
|
||||
{
|
||||
envServerDir = current_path();
|
||||
setenv("TES3MP_SERVER_DIR", envServerDir.c_str(), 1);
|
||||
}
|
||||
|
||||
addGlobalPackagePath(envServerDir.string() + "/lib/lua/?/init.lua;" + envServerDir.string() + "/lib/lua/?.lua");
|
||||
addGlobalCPath(envServerDir.string() + "lib/?" + libExt);
|
||||
funcLoadMods(envServerDir);
|
||||
|
||||
|
||||
if (envServerUserDir != nullptr)
|
||||
{
|
||||
funcLoadMods(envServerUserDir);
|
||||
addGlobalPackagePath(string(envServerUserDir) + "/lib/lua/?/init.lua;" + string(envServerUserDir) + "/lib/lua/?.lua");
|
||||
|
||||
}
|
||||
|
||||
for (auto &mod : mods)
|
||||
{
|
||||
const string &modName = mod.first;
|
||||
sol::environment &modEnv = mod.second;
|
||||
sol::table dependencies = modEnv["ModInfo"]["dependencies"];
|
||||
for (auto &dependency : dependencies)
|
||||
{
|
||||
int idx = dependency.first.as<int>();
|
||||
sol::table dep = dependency.second;
|
||||
const std::string depNameRequest = dep[1];
|
||||
const std::string depVersionRequest = dep[2];
|
||||
|
||||
cout << "\"" << idx << "\": \"" << depNameRequest << "\" \"" << depVersionRequest << "\"" << endl;
|
||||
const auto &depEnvIt = mods.find(depNameRequest);
|
||||
if (depEnvIt != mods.end())
|
||||
{
|
||||
string depVersionFound = depEnvIt->second["ModInfo"]["version"];
|
||||
if (CompVersion(depVersionRequest, depVersionFound) != 0)
|
||||
{
|
||||
stringstream sstr;
|
||||
sstr << depNameRequest << ": version \"" << depVersionFound
|
||||
<< "\" is not applicable for \"" << modName << "\" expected \""
|
||||
<< depVersionRequest + "\"";
|
||||
throw runtime_error(sstr.str());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
stringstream sstr;
|
||||
sstr << depNameRequest + " \"" << depVersionRequest << "\" not found.";
|
||||
throw runtime_error(sstr.str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dataEnv["Core"]["LOADED_MODS"] = mods.size();
|
||||
|
||||
eventCtrl->Call<CoreEvent::ON_POST_INIT>();
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
//
|
||||
// Created by koncord on 01.08.17.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "sol.hpp"
|
||||
#include "CommandController.hpp"
|
||||
#include "Timer.hpp"
|
||||
#include <unordered_map>
|
||||
#include <memory>
|
||||
#include <apps/openmw-mp/Actors.hpp>
|
||||
#include <apps/openmw-mp/Object.hpp>
|
||||
|
||||
//class CommandController;
|
||||
class EventController;
|
||||
//class TimerController;
|
||||
|
||||
class LuaState
|
||||
{
|
||||
public:
|
||||
LuaState();
|
||||
~LuaState() = default;
|
||||
std::shared_ptr<sol::state> getState() { return lua; }
|
||||
void addGlobalPackagePath(const std::string &path);
|
||||
void addGlobalCPath(const std::string &path);
|
||||
sol::table getCoreTable() { return dataEnv["Core"]; }
|
||||
sol::environment &getDataEnv(){ return dataEnv; }
|
||||
void loadMods();
|
||||
|
||||
CommandController &getCmdCtrl();
|
||||
EventController &getEventCtrl();
|
||||
TimerController &getTimerCtrl();
|
||||
ObjectController &getObjectCtrl();
|
||||
|
||||
ActorController &getActorCtrl();
|
||||
|
||||
private:
|
||||
sol::environment openScript(std::string path, std::string modname);
|
||||
private:
|
||||
std::shared_ptr<sol::state> lua;
|
||||
sol::environment dataEnv;
|
||||
std::unique_ptr<CommandController> cmdCtrl;
|
||||
std::unique_ptr<EventController> eventCtrl;
|
||||
std::unique_ptr<TimerController> timerCtrl;
|
||||
std::unique_ptr<ActorController> actorCtrl;
|
||||
std::unique_ptr<ObjectController> objectCtrl;
|
||||
std::unordered_map<std::string, sol::environment> mods;
|
||||
};
|
@ -1,20 +0,0 @@
|
||||
//
|
||||
// Created by koncord on 23.01.16.
|
||||
//
|
||||
|
||||
#ifndef PLATFORM_HPP
|
||||
#define PLATFORM_HPP
|
||||
|
||||
#if _MSC_VER
|
||||
#ifdef _M_X86
|
||||
#define ARCH_X86
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if __GNUC__
|
||||
#ifdef __i386__
|
||||
#define ARCH_X86
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif //PLATFORM_HPP
|
@ -1,109 +0,0 @@
|
||||
//
|
||||
// Created by koncord on 19.03.16.
|
||||
//
|
||||
|
||||
#include "Script.hpp"
|
||||
#include "LangNative/LangNative.hpp"
|
||||
|
||||
#if defined (ENABLE_PAWN)
|
||||
#include "LangPawn/LangPAWN.hpp"
|
||||
#endif
|
||||
#if defined (ENABLE_LUA)
|
||||
#include "LangLua/LangLua.hpp"
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
|
||||
Script::ScriptList Script::scripts;
|
||||
|
||||
Script::Script(const char *path)
|
||||
{
|
||||
FILE *file = fopen(path, "rb");
|
||||
|
||||
if (!file)
|
||||
throw runtime_error("Script not found: " + string(path));
|
||||
|
||||
fclose(file);
|
||||
|
||||
#ifdef _WIN32
|
||||
if (strstr(path, ".dll"))
|
||||
#else
|
||||
if (strstr(path, ".so"))
|
||||
#endif
|
||||
{
|
||||
script_type = SCRIPT_CPP;
|
||||
lang = new LangNative();
|
||||
}
|
||||
#if defined (ENABLE_PAWN)
|
||||
else if (strstr(path, ".amx"))
|
||||
{
|
||||
lang = new LangPAWN();
|
||||
script_type = SCRIPT_PAWN;
|
||||
}
|
||||
#endif
|
||||
#if defined (ENABLE_LUA)
|
||||
else if (strstr(path, ".lua") || strstr(path, ".t"))
|
||||
{
|
||||
lang = new LangLua();
|
||||
script_type = SCRIPT_LUA;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
throw runtime_error("Script type not recognized: " + string(path));
|
||||
|
||||
try
|
||||
{
|
||||
lang->LoadProgram(path);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
lang->FreeProgram();
|
||||
throw;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
Script::~Script()
|
||||
{
|
||||
lang->FreeProgram();
|
||||
|
||||
delete lang;
|
||||
}
|
||||
|
||||
void Script::LoadScripts(char *scripts, const char *base)
|
||||
{
|
||||
char *token = strtok(scripts, ",");
|
||||
|
||||
try
|
||||
{
|
||||
while (token)
|
||||
{
|
||||
char path[4096];
|
||||
snprintf(path, sizeof(path), Utils::convertPath("%s/%s/%s").c_str(), base, "scripts", token);
|
||||
Script::scripts.emplace_back(new Script(path));
|
||||
token = strtok(nullptr, ",");
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
UnloadScripts();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void Script::UnloadScripts()
|
||||
{
|
||||
//Public::DeleteAll();
|
||||
scripts.clear();
|
||||
#if defined (ENABLE_TERRA)
|
||||
terra_llvmshutdown();
|
||||
#endif
|
||||
}
|
||||
|
||||
void Script::LoadScript(const char *script, const char *base)
|
||||
{
|
||||
char path[4096];
|
||||
snprintf(path, sizeof(path), Utils::convertPath("%s/%s/%s").c_str(), base, "scripts", script);
|
||||
Script::scripts.emplace_back(new Script(path));
|
||||
}
|
@ -1,156 +0,0 @@
|
||||
//
|
||||
// Created by koncord on 19.03.16.
|
||||
//
|
||||
|
||||
#ifndef PLUGINSYSTEM3_SCRIPT_HPP
|
||||
#define PLUGINSYSTEM3_SCRIPT_HPP
|
||||
#include "Types.hpp"
|
||||
#include "SystemInterface.hpp"
|
||||
#include "ScriptFunction.hpp"
|
||||
#include "ScriptFunctions.hpp"
|
||||
#include "Language.hpp"
|
||||
|
||||
#include <boost/any.hpp>
|
||||
#include <unordered_map>
|
||||
#include <memory>
|
||||
|
||||
class Script : private ScriptFunctions
|
||||
{
|
||||
// http://imgur.com/hU0N4EH
|
||||
private:
|
||||
|
||||
Language *lang;
|
||||
|
||||
enum
|
||||
{
|
||||
SCRIPT_CPP,
|
||||
SCRIPT_PAWN,
|
||||
SCRIPT_LUA
|
||||
};
|
||||
|
||||
template<typename R>
|
||||
R GetScript(const char *name)
|
||||
{
|
||||
if (script_type == SCRIPT_CPP)
|
||||
{
|
||||
return SystemInterface<R>(lang->GetInterface(), name).result;
|
||||
}
|
||||
else
|
||||
{
|
||||
return reinterpret_cast<R>(lang->IsCallbackPresent(name));
|
||||
}
|
||||
}
|
||||
|
||||
int script_type;
|
||||
std::unordered_map<unsigned int, FunctionEllipsis<void>> callbacks_;
|
||||
|
||||
typedef std::vector<std::unique_ptr<Script>> ScriptList;
|
||||
static ScriptList scripts;
|
||||
|
||||
Script(const char *path);
|
||||
|
||||
Script(const Script&) = delete;
|
||||
Script& operator=(const Script&) = delete;
|
||||
|
||||
public:
|
||||
~Script();
|
||||
|
||||
static void LoadScript(const char *script, const char* base);
|
||||
static void LoadScripts(char* scripts, const char* base);
|
||||
static void UnloadScripts();
|
||||
|
||||
static constexpr ScriptCallbackData const& CallBackData(const unsigned int I, const unsigned int N = 0) {
|
||||
return callbacks[N].index == I ? callbacks[N] : CallBackData(I, N + 1);
|
||||
}
|
||||
|
||||
template<unsigned int I>
|
||||
using CallBackReturn = typename CharType<CallBackData(I).callback.ret>::type;
|
||||
|
||||
template<size_t N>
|
||||
static constexpr unsigned int CallbackIdentity(const char(&str)[N])
|
||||
{
|
||||
return Utils::hash(str);
|
||||
}
|
||||
|
||||
|
||||
template<unsigned int I, bool B = false, typename... Args>
|
||||
static unsigned int Call(CallBackReturn<I>& result, Args&&... args) {
|
||||
constexpr ScriptCallbackData const& data = CallBackData(I);
|
||||
static_assert(data.callback.matches(TypeString<typename std::remove_reference<Args>::type...>::value),
|
||||
"Wrong number or types of arguments");
|
||||
|
||||
unsigned int count = 0;
|
||||
|
||||
for (auto& script : scripts)
|
||||
{
|
||||
if (!script->callbacks_.count(I))
|
||||
script->callbacks_.emplace(I, script->GetScript<FunctionEllipsis<void>>(data.name));
|
||||
|
||||
auto callback = script->callbacks_[I];
|
||||
|
||||
if (!callback)
|
||||
continue;
|
||||
|
||||
|
||||
LOG_MESSAGE_SIMPLE(Log::LOG_VERBOSE, "Called function \"%s\"", data.name);
|
||||
|
||||
if (script->script_type == SCRIPT_CPP)
|
||||
result = reinterpret_cast<FunctionEllipsis<CallBackReturn<I>>>(callback)(std::forward<Args>(args)...);
|
||||
#if defined (ENABLE_PAWN)
|
||||
else if (script->script_type == SCRIPT_PAWN)
|
||||
{
|
||||
boost::any any = script->lang->Call(data.name, data.callback.types, B, std::forward<Args>(args)...);
|
||||
result = reinterpret_cast<CallBackReturn<I>> ((int)boost::any_cast<int64_t>(any)); // TODO: WTF?! int?!
|
||||
}
|
||||
#endif
|
||||
#if defined (ENABLE_LUA)
|
||||
else if (script->script_type == SCRIPT_LUA)
|
||||
{
|
||||
boost::any any = script->lang->Call(data.name, data.callback.types, B, std::forward<Args>(args)...);
|
||||
result = static_cast<CallBackReturn<I>>(boost::any_cast<luabridge::LuaRef>(any).cast<CallBackReturn<I>>());
|
||||
}
|
||||
#endif
|
||||
++count;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
template<unsigned int I, bool B = false, typename... Args>
|
||||
static unsigned int Call(Args&&... args) {
|
||||
constexpr ScriptCallbackData const& data = CallBackData(I);
|
||||
static_assert(data.callback.matches(TypeString<typename std::remove_reference<Args>::type...>::value),
|
||||
"Wrong number or types of arguments");
|
||||
|
||||
unsigned int count = 0;
|
||||
|
||||
for (auto& script : scripts)
|
||||
{
|
||||
if (!script->callbacks_.count(I))
|
||||
script->callbacks_.emplace(I, script->GetScript<FunctionEllipsis<void>>(data.name));
|
||||
|
||||
auto callback = script->callbacks_[I];
|
||||
|
||||
if (!callback)
|
||||
continue;
|
||||
|
||||
LOG_MESSAGE_SIMPLE(Log::LOG_VERBOSE, "Called function \"%s\"", data.name);
|
||||
|
||||
if (script->script_type == SCRIPT_CPP)
|
||||
reinterpret_cast<FunctionEllipsis<CallBackReturn<I>>>(callback)(std::forward<Args>(args)...);
|
||||
#if defined (ENABLE_PAWN)
|
||||
else if (script->script_type == SCRIPT_PAWN)
|
||||
script->lang->Call(data.name, data.callback.types, B, std::forward<Args>(args)...);
|
||||
#endif
|
||||
#if defined (ENABLE_LUA)
|
||||
else if (script->script_type == SCRIPT_LUA)
|
||||
script->lang->Call(data.name, data.callback.types, B, std::forward<Args>(args)...);
|
||||
#endif
|
||||
++count;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
};
|
||||
|
||||
#endif //PLUGINSYSTEM3_SCRIPT_HPP
|
@ -1,167 +0,0 @@
|
||||
//
|
||||
// Created by koncord on 23.01.16.
|
||||
//
|
||||
|
||||
#include<iostream>
|
||||
#include <stdexcept>
|
||||
#include "ScriptFunction.hpp"
|
||||
|
||||
#if !defined(_WIN32) && !defined(__ARM_ARCH) // temporarily disabled
|
||||
#include <call.hpp>
|
||||
#endif
|
||||
|
||||
#if defined (ENABLE_LUA)
|
||||
#include "LangLua/LangLua.hpp"
|
||||
#endif
|
||||
|
||||
#if defined (ENABLE_PAWN)
|
||||
#include "LangPawn/LangPAWN.hpp"
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
|
||||
ScriptFunction::ScriptFunction(ScriptFunc fCpp,char ret_type, const string &def) :
|
||||
fCpp(fCpp), ret_type(ret_type), def(def), script_type(SCRIPT_CPP)
|
||||
{
|
||||
|
||||
}
|
||||
#if defined (ENABLE_LUA)
|
||||
ScriptFunction::ScriptFunction(const ScriptFuncLua &fLua, lua_State *lua, char ret_type, const std::string &def) :
|
||||
fLua({lua, fLua}), ret_type(ret_type), def(def), script_type(SCRIPT_LUA)
|
||||
{
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined (ENABLE_PAWN)
|
||||
ScriptFunction::ScriptFunction(const ScriptFuncPAWN &fPawn, AMX *amx, char ret_type, const string &def) :
|
||||
fPawn({amx, fPawn}), def(def), ret_type(ret_type), script_type(SCRIPT_PAWN)
|
||||
{
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
ScriptFunction::~ScriptFunction()
|
||||
{
|
||||
#if defined (ENABLE_PAWN)
|
||||
if (script_type == SCRIPT_PAWN)
|
||||
fPawn.name.~ScriptFuncPAWN();
|
||||
#if defined (ENABLE_LUA)
|
||||
else
|
||||
#endif
|
||||
#endif
|
||||
#if defined (ENABLE_LUA)
|
||||
if (script_type == SCRIPT_LUA)
|
||||
fLua.name.~ScriptFuncLua();
|
||||
#endif
|
||||
}
|
||||
|
||||
boost::any ScriptFunction::Call(const vector<boost::any> &args)
|
||||
{
|
||||
boost::any result;
|
||||
|
||||
if (def.length() != args.size())
|
||||
throw runtime_error("Script call: Number of arguments does not match definition");
|
||||
#if defined (ENABLE_PAWN)
|
||||
if (script_type == SCRIPT_PAWN)
|
||||
{
|
||||
LangPAWN langPawn(fPawn.amx);
|
||||
boost::any any = langPawn.Call(fPawn.name.c_str(), def.c_str(), args);
|
||||
result = boost::any();
|
||||
|
||||
cell ret = boost::any_cast<cell>(any);
|
||||
|
||||
switch (ret_type)
|
||||
{
|
||||
case 'i':
|
||||
result = static_cast<unsigned int>(ret);
|
||||
break;
|
||||
case 'q':
|
||||
result = static_cast<signed int>(ret);
|
||||
break;
|
||||
case 's':
|
||||
throw runtime_error("Pawn call: the Pawn does not supported strings in public functions");
|
||||
case 'f':
|
||||
|
||||
result = static_cast<double>(amx_ctof(ret));
|
||||
break;
|
||||
case 'v':
|
||||
result = boost::any();
|
||||
break;
|
||||
default:
|
||||
throw runtime_error("Pawn call: Unknown return type" + ret_type);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined (ENABLE_LUA)
|
||||
else if (script_type == SCRIPT_LUA)
|
||||
{
|
||||
LangLua langLua(fLua.lua);
|
||||
boost::any any = langLua.Call(fLua.name.c_str(), def.c_str(), args);
|
||||
|
||||
switch (ret_type)
|
||||
{
|
||||
case 'i':
|
||||
result = boost::any_cast<luabridge::LuaRef>(any).cast<unsigned int>();
|
||||
break;
|
||||
case 'q':
|
||||
result = boost::any_cast<luabridge::LuaRef>(any).cast<signed int>();
|
||||
break;
|
||||
case 'f':
|
||||
result = boost::any_cast<luabridge::LuaRef>(any).cast<double>();
|
||||
break;
|
||||
case 's':
|
||||
result = boost::any_cast<luabridge::LuaRef>(any).cast<const char*>();
|
||||
break;
|
||||
case 'v':
|
||||
result = boost::any();
|
||||
break;
|
||||
default:
|
||||
throw runtime_error("Lua call: Unknown return type" + ret_type);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
#if !defined(_WIN32) && !defined(__ARM_ARCH) // temporarily disabled
|
||||
string::iterator it;
|
||||
vector<boost::any>::const_iterator it2;
|
||||
vector<intptr_t> data;
|
||||
CallArgs callArgs;
|
||||
|
||||
for (it = def.begin(), it2 = args.begin(); it != def.end(); ++it, ++it2)
|
||||
{
|
||||
switch (*it)
|
||||
{
|
||||
case 'i':
|
||||
callArgs.push_integer(boost::any_cast<unsigned int>(*it2));
|
||||
break;
|
||||
case 'q':
|
||||
callArgs.push_integer(boost::any_cast<signed int>(*it2));
|
||||
break;
|
||||
case 'f':
|
||||
callArgs.push_double(boost::any_cast<double>(*it2));
|
||||
break;
|
||||
case 'd':
|
||||
callArgs.push_double(boost::any_cast<double*>(*it2));
|
||||
break;
|
||||
case 's':
|
||||
callArgs.push_stringPtr(boost::any_cast<const char *>(*it2));
|
||||
break;
|
||||
case 'v':
|
||||
result = boost::any();
|
||||
break;
|
||||
default:
|
||||
throw runtime_error("C++ call: Unknown argument identifier " + *it);
|
||||
}
|
||||
}
|
||||
Func f = reinterpret_cast<Func>(fCpp);
|
||||
result = ::Call(f, callArgs);
|
||||
#else
|
||||
throw runtime_error("C++ call: Windows and ARM not supported yet.");
|
||||
#endif
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
@ -1,72 +0,0 @@
|
||||
//
|
||||
// Created by koncord on 23.01.16.
|
||||
//
|
||||
|
||||
#ifndef SCRIPTFUNCTION_HPP
|
||||
#define SCRIPTFUNCTION_HPP
|
||||
|
||||
#include <boost/any.hpp>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#if defined (ENABLE_LUA)
|
||||
#include "LangLua/LangLua.hpp"
|
||||
#endif
|
||||
|
||||
#if defined (ENABLE_PAWN)
|
||||
#include <amx.h>
|
||||
#endif
|
||||
|
||||
typedef unsigned long long(*ScriptFunc)();
|
||||
#if defined (ENABLE_PAWN)
|
||||
typedef std::string ScriptFuncPAWN;
|
||||
#endif
|
||||
#if defined (ENABLE_LUA)
|
||||
typedef std::string ScriptFuncLua;
|
||||
#endif
|
||||
|
||||
class ScriptFunction
|
||||
{
|
||||
protected:
|
||||
union
|
||||
{
|
||||
ScriptFunc fCpp;
|
||||
#if defined (ENABLE_PAWN)
|
||||
struct
|
||||
{
|
||||
AMX *amx;
|
||||
ScriptFuncPAWN name;
|
||||
} fPawn;
|
||||
#endif
|
||||
#if defined (ENABLE_LUA)
|
||||
struct
|
||||
{
|
||||
lua_State *lua;
|
||||
ScriptFuncLua name;
|
||||
} fLua;
|
||||
#endif
|
||||
};
|
||||
|
||||
protected:
|
||||
char ret_type;
|
||||
std::string def;
|
||||
int script_type;
|
||||
enum
|
||||
{
|
||||
SCRIPT_CPP,
|
||||
SCRIPT_PAWN,
|
||||
SCRIPT_LUA
|
||||
};
|
||||
|
||||
ScriptFunction(ScriptFunc fCpp, char ret_type, const std::string &def);
|
||||
#if defined (ENABLE_LUA)
|
||||
ScriptFunction(const ScriptFuncLua &fPawn, lua_State *lua, char ret_type, const std::string &def);
|
||||
#endif
|
||||
#if defined (ENABLE_PAWN)
|
||||
ScriptFunction(const ScriptFuncPAWN &fPawn, AMX *amx, char ret_type, const std::string &def);
|
||||
#endif
|
||||
virtual ~ScriptFunction();
|
||||
|
||||
boost::any Call(const std::vector<boost::any> &args);
|
||||
};
|
||||
|
||||
#endif //SCRIPTFUNCTION_HPP
|
@ -1,174 +0,0 @@
|
||||
//
|
||||
// Created by koncord on 24.01.16.
|
||||
//
|
||||
|
||||
#include "ScriptFunctions.hpp"
|
||||
#include "API/PublicFnAPI.hpp"
|
||||
#include <cstdarg>
|
||||
#include <iostream>
|
||||
#include <apps/openmw-mp/Player.hpp>
|
||||
#include <apps/openmw-mp/Networking.hpp>
|
||||
#include <components/openmw-mp/NetworkMessages.hpp>
|
||||
#include <components/openmw-mp/Version.hpp>
|
||||
#include "MasterClient.hpp"
|
||||
|
||||
template<typename... Types>
|
||||
constexpr char TypeString<Types...>::value[];
|
||||
constexpr ScriptFunctionData ScriptFunctions::functions[];
|
||||
constexpr ScriptCallbackData ScriptFunctions::callbacks[];
|
||||
|
||||
using namespace std;
|
||||
|
||||
void ScriptFunctions::GetArguments(std::vector<boost::any> ¶ms, va_list args, const std::string &def)
|
||||
{
|
||||
params.reserve(def.length());
|
||||
|
||||
try
|
||||
{
|
||||
for (char c : def)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case 'i':
|
||||
params.emplace_back(va_arg(args, unsigned int));
|
||||
break;
|
||||
|
||||
case 'q':
|
||||
params.emplace_back(va_arg(args, signed int));
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
params.emplace_back(va_arg(args, unsigned long long));
|
||||
break;
|
||||
|
||||
case 'w':
|
||||
params.emplace_back(va_arg(args, signed long long));
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
params.emplace_back(va_arg(args, double));
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
params.emplace_back(va_arg(args, void*));
|
||||
break;
|
||||
|
||||
case 's':
|
||||
params.emplace_back(va_arg(args, const char*));
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
params.emplace_back(va_arg(args, int));
|
||||
break;
|
||||
|
||||
default:
|
||||
throw runtime_error("C++ call: Unknown argument identifier " + c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
catch (...)
|
||||
{
|
||||
va_end(args);
|
||||
throw;
|
||||
}
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void ScriptFunctions::MakePublic(ScriptFunc _public, const char *name, char ret_type, const char *def) noexcept
|
||||
{
|
||||
Public::MakePublic(_public, name, ret_type, def);
|
||||
}
|
||||
|
||||
boost::any ScriptFunctions::CallPublic(const char *name, va_list args) noexcept
|
||||
{
|
||||
vector<boost::any> params;
|
||||
|
||||
try
|
||||
{
|
||||
string def = Public::GetDefinition(name);
|
||||
GetArguments(params, args, def);
|
||||
|
||||
return Public::Call(name, params);
|
||||
}
|
||||
catch (...) {}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ScriptFunctions::StopServer(int code) noexcept
|
||||
{
|
||||
mwmp::Networking::getPtr()->stopServer(code);
|
||||
}
|
||||
|
||||
void ScriptFunctions::Kick(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,);
|
||||
mwmp::Networking::getPtr()->kickPlayer(player->guid);
|
||||
}
|
||||
|
||||
void ScriptFunctions::BanAddress(const char *ipAddress) noexcept
|
||||
{
|
||||
mwmp::Networking::getPtr()->banAddress(ipAddress);
|
||||
}
|
||||
|
||||
void ScriptFunctions::UnbanAddress(const char *ipAddress) noexcept
|
||||
{
|
||||
mwmp::Networking::getPtr()->unbanAddress(ipAddress);
|
||||
}
|
||||
|
||||
const char *ScriptFunctions::GetServerVersion() noexcept
|
||||
{
|
||||
return TES3MP_VERSION;
|
||||
}
|
||||
|
||||
const char *ScriptFunctions::GetProtocolVersion() noexcept
|
||||
{
|
||||
static string version = to_string(TES3MP_PROTO_VERSION);
|
||||
return version.c_str();
|
||||
}
|
||||
|
||||
int ScriptFunctions::GetAvgPing(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player,-1);
|
||||
return mwmp::Networking::get().getAvgPing(player->guid);
|
||||
}
|
||||
|
||||
const char *ScriptFunctions::GetIP(unsigned short pid) noexcept
|
||||
{
|
||||
Player *player;
|
||||
GET_PLAYER(pid, player, "");
|
||||
RakNet::SystemAddress addr = mwmp::Networking::getPtr()->getSystemAddress(player->guid);
|
||||
return addr.ToString(false);
|
||||
}
|
||||
|
||||
void ScriptFunctions::SetModname(const char *name) noexcept
|
||||
{
|
||||
mwmp::Networking::getPtr()->getMasterClient()->SetModname(name);
|
||||
}
|
||||
|
||||
void ScriptFunctions::SetHostname(const char *name) noexcept
|
||||
{
|
||||
mwmp::Networking::getPtr()->getMasterClient()->SetHostname(name);
|
||||
}
|
||||
|
||||
void ScriptFunctions::SetServerPassword(const char *passw) noexcept
|
||||
{
|
||||
mwmp::Networking::getPtr()->setServerPassword(passw);
|
||||
}
|
||||
|
||||
void ScriptFunctions::SetRuleString(const char *key, const char *value) noexcept
|
||||
{
|
||||
auto mc = mwmp::Networking::getPtr()->getMasterClient();
|
||||
if (mc)
|
||||
mc->SetRuleString(key, value);
|
||||
}
|
||||
|
||||
void ScriptFunctions::SetRuleValue(const char *key, double value) noexcept
|
||||
{
|
||||
auto mc = mwmp::Networking::getPtr()->getMasterClient();
|
||||
if (mc)
|
||||
mc->SetRuleValue(key, value);
|
||||
}
|
@ -1,186 +0,0 @@
|
||||
//
|
||||
// Created by koncord on 24.01.16.
|
||||
//
|
||||
|
||||
#ifndef SCRIPTFUNCTIONS_HPP
|
||||
#define SCRIPTFUNCTIONS_HPP
|
||||
|
||||
#include <Script/Functions/Actors.hpp>
|
||||
#include <Script/Functions/Books.hpp>
|
||||
#include <Script/Functions/Cells.hpp>
|
||||
#include <Script/Functions/CharClass.hpp>
|
||||
#include <Script/Functions/Dialogue.hpp>
|
||||
#include <Script/Functions/Factions.hpp>
|
||||
#include <Script/Functions/GUI.hpp>
|
||||
#include <Script/Functions/Items.hpp>
|
||||
#include <Script/Functions/Mechanics.hpp>
|
||||
#include <Script/Functions/Miscellaneous.hpp>
|
||||
#include <Script/Functions/Positions.hpp>
|
||||
#include <Script/Functions/Quests.hpp>
|
||||
#include <Script/Functions/Settings.hpp>
|
||||
#include <Script/Functions/Spells.hpp>
|
||||
#include <Script/Functions/Stats.hpp>
|
||||
#include <Script/Functions/World.hpp>
|
||||
#include <RakNetTypes.h>
|
||||
//#include <amx/amx.h>
|
||||
#include <tuple>
|
||||
#include <apps/openmw-mp/Player.hpp>
|
||||
#include "ScriptFunction.hpp"
|
||||
#include "Types.hpp"
|
||||
|
||||
#include <components/openmw-mp/Log.hpp>
|
||||
|
||||
#define GET_PLAYER(pid, pl, retvalue) \
|
||||
pl = Players::getPlayer(pid); \
|
||||
if (player == 0) {\
|
||||
LOG_MESSAGE_SIMPLE(Log::LOG_ERROR, "%s: Player with pid \'%d\' not found\n", __PRETTY_FUNCTION__, pid);\
|
||||
/*ScriptFunctions::StopServer(1);*/ \
|
||||
return retvalue;\
|
||||
}
|
||||
|
||||
|
||||
class ScriptFunctions
|
||||
{
|
||||
public:
|
||||
|
||||
static void GetArguments(std::vector<boost::any> ¶ms, va_list args, const std::string &def);
|
||||
|
||||
static void StopServer(int code) noexcept;
|
||||
|
||||
static void MakePublic(ScriptFunc _public, const char *name, char ret_type, const char *def) noexcept;
|
||||
static boost::any CallPublic(const char *name, va_list args) noexcept;
|
||||
|
||||
static void SendMessage(unsigned short pid, const char *message, bool broadcast) noexcept;
|
||||
static void CleanChatByPid(unsigned short pid);
|
||||
static void CleanChat();
|
||||
|
||||
/**
|
||||
* \brief Create timer
|
||||
* \param callback
|
||||
* \param msec
|
||||
* \return return timer id
|
||||
*/
|
||||
static int CreateTimer(ScriptFunc callback, int msec) noexcept;
|
||||
static int CreateTimerEx(ScriptFunc callback, int msec, const char *types, va_list args) noexcept;
|
||||
|
||||
static void StartTimer(int timerId) noexcept;
|
||||
static void StopTimer(int timerId) noexcept;
|
||||
static void RestartTimer(int timerId, int msec) noexcept;
|
||||
static void FreeTimer(int timerId) noexcept;
|
||||
static bool IsTimerElapsed(int timerId) noexcept;
|
||||
|
||||
static void Kick(unsigned short pid) noexcept;
|
||||
static void BanAddress(const char *ipAddress) noexcept;
|
||||
static void UnbanAddress(const char *ipAddress) noexcept;
|
||||
|
||||
static const char *GetServerVersion() noexcept;
|
||||
static const char *GetProtocolVersion() noexcept;
|
||||
static int GetAvgPing(unsigned short pid) noexcept;
|
||||
static const char* GetIP(unsigned short pid) noexcept;
|
||||
static void SetModname(const char* name) noexcept;
|
||||
static void SetHostname(const char* name) noexcept;
|
||||
static void SetServerPassword(const char *passw) noexcept;
|
||||
static void SetRuleString(const char *key, const char *value) noexcept;
|
||||
static void SetRuleValue(const char *key, double value) noexcept;
|
||||
|
||||
static constexpr ScriptFunctionData functions[]{
|
||||
{"CreateTimer", ScriptFunctions::CreateTimer},
|
||||
{"CreateTimerEx", reinterpret_cast<Function<void>>(ScriptFunctions::CreateTimerEx)},
|
||||
{"MakePublic", ScriptFunctions::MakePublic},
|
||||
{"CallPublic", reinterpret_cast<Function<void>>(ScriptFunctions::CallPublic)},
|
||||
|
||||
{"StartTimer", ScriptFunctions::StartTimer},
|
||||
{"StopTimer", ScriptFunctions::StopTimer},
|
||||
{"RestartTimer", ScriptFunctions::RestartTimer},
|
||||
{"FreeTimer", ScriptFunctions::FreeTimer},
|
||||
{"IsTimerElapsed", ScriptFunctions::IsTimerElapsed},
|
||||
|
||||
{"StopServer", ScriptFunctions::StopServer},
|
||||
|
||||
{"SendMessage", ScriptFunctions::SendMessage},
|
||||
|
||||
{"Kick", ScriptFunctions::Kick},
|
||||
{"BanAddress", ScriptFunctions::BanAddress},
|
||||
{"UnbanAddress", ScriptFunctions::UnbanAddress},
|
||||
|
||||
{"GetServerVersion", ScriptFunctions::GetServerVersion},
|
||||
{"GetProtocolVersion", ScriptFunctions::GetProtocolVersion},
|
||||
{"GetAvgPing", ScriptFunctions::GetAvgPing},
|
||||
{"SetModname", ScriptFunctions::SetModname},
|
||||
{"SetHostname", ScriptFunctions::SetHostname},
|
||||
{"SetServerPassword", ScriptFunctions::SetServerPassword},
|
||||
{"SetRuleString", ScriptFunctions::SetRuleString},
|
||||
{"SetRuleValue", ScriptFunctions::SetRuleValue},
|
||||
{"CleanChatByPid", ScriptFunctions::CleanChatByPid},
|
||||
{"CleanChat", ScriptFunctions::CleanChat},
|
||||
{"GetIP", ScriptFunctions::GetIP},
|
||||
|
||||
ACTORAPI,
|
||||
BOOKAPI,
|
||||
CELLAPI,
|
||||
CHARCLASSAPI,
|
||||
DIALOGUEAPI,
|
||||
FACTIONAPI,
|
||||
GUIAPI,
|
||||
ITEMAPI,
|
||||
MECHANICSAPI,
|
||||
MISCELLANEOUSAPI,
|
||||
POSITIONAPI,
|
||||
QUESTAPI,
|
||||
SETTINGSAPI,
|
||||
SPELLAPI,
|
||||
STATAPI,
|
||||
WORLDAPI
|
||||
};
|
||||
|
||||
static constexpr ScriptCallbackData callbacks[]{
|
||||
{"Main", Function<int, int, int>()},
|
||||
{"OnServerInit", Function<void>()},
|
||||
{"OnServerPostInit", Function<void>()},
|
||||
{"OnServerExit", Function<void, bool>()},
|
||||
{"OnPlayerConnect", Function<bool, unsigned short>()},
|
||||
{"OnPlayerDisconnect", Function<void, unsigned short>()},
|
||||
{"OnPlayerDeath", Function<void, unsigned short>()},
|
||||
{"OnPlayerResurrect", Function<void, unsigned short>()},
|
||||
{"OnPlayerCellChange", Function<void, unsigned short>()},
|
||||
{"OnPlayerKillCount", Function<void, unsigned short>()},
|
||||
{"OnPlayerAttribute", Function<void, unsigned short>()},
|
||||
{"OnPlayerSkill", Function<void, unsigned short>()},
|
||||
{"OnPlayerLevel", Function<void, unsigned short>()},
|
||||
{"OnPlayerBounty", Function<void, unsigned short>()},
|
||||
{"OnPlayerEquipment", Function<void, unsigned short>()},
|
||||
{"OnPlayerInventory", Function<void, unsigned short>()},
|
||||
{"OnPlayerJournal", Function<void, unsigned short>()},
|
||||
{"OnPlayerFaction", Function<void, unsigned short>()},
|
||||
{"OnPlayerShapeshift", Function<void, unsigned short>()},
|
||||
{"OnPlayerSpellbook", Function<void, unsigned short>()},
|
||||
{"OnPlayerTopic", Function<void, unsigned short>()},
|
||||
{"OnPlayerDisposition", Function<void, unsigned short>()},
|
||||
{"OnPlayerBook", Function<void, unsigned short>()},
|
||||
{"OnPlayerMap", Function<void, unsigned short>()},
|
||||
{"OnPlayerRest", Function<void, unsigned short>()},
|
||||
{"OnCellLoad", Function<void, unsigned short, const char*>()},
|
||||
{"OnCellUnload", Function<void, unsigned short, const char*>()},
|
||||
{"OnCellDeletion", Function<void, const char*>()},
|
||||
{"OnContainer", Function<void, unsigned short, const char*>()},
|
||||
{"OnDoorState", Function<void, unsigned short, const char*>()},
|
||||
{"OnObjectPlace", Function<void, unsigned short, const char*>()},
|
||||
{"OnObjectState", Function<void, unsigned short, const char*>()},
|
||||
{"OnObjectSpawn", Function<void, unsigned short, const char*>()},
|
||||
{"OnObjectDelete", Function<void, unsigned short, const char*>()},
|
||||
{"OnObjectLock", Function<void, unsigned short, const char*>()},
|
||||
{"OnObjectScale", Function<void, unsigned short, const char*>()},
|
||||
{"OnObjectTrap", Function<void, unsigned short, const char*>()},
|
||||
{"OnActorList", Function<void, unsigned short, const char*>()},
|
||||
{"OnActorEquipment", Function<void, unsigned short, const char*>()},
|
||||
{"OnActorCellChange", Function<void, unsigned short, const char*>()},
|
||||
{"OnActorTest", Function<void, unsigned short, const char*>()},
|
||||
{"OnPlayerSendMessage", Function<bool, unsigned short, const char*>()},
|
||||
{"OnPlayerEndCharGen", Function<void, unsigned short>()},
|
||||
{"OnGUIAction", Function<void, unsigned short, int, const char*>()},
|
||||
{"OnMpNumIncrement", Function<void, int>()},
|
||||
{"OnRequestPluginList", Function<const char *, unsigned int, unsigned int>()}
|
||||
};
|
||||
};
|
||||
|
||||
#endif //SCRIPTFUNCTIONS_HPP
|
@ -1,43 +0,0 @@
|
||||
//
|
||||
// Created by koncord on 19.03.16.
|
||||
//
|
||||
|
||||
#ifndef PLUGINSYSTEM3_SYSTEMINTERFACE_HPP
|
||||
#define PLUGINSYSTEM3_SYSTEMINTERFACE_HPP
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#else
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
#include "Types.hpp"
|
||||
|
||||
template<typename R = void*>
|
||||
struct SystemInterface
|
||||
{
|
||||
|
||||
union
|
||||
{
|
||||
R result;
|
||||
#ifdef _WIN32
|
||||
decltype(GetProcAddress(lib_t(), nullptr)) data;
|
||||
#else
|
||||
decltype(dlsym(lib_t(), nullptr)) data;
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifndef _WIN32
|
||||
static_assert(sizeof(result) == sizeof(data), "R should have the same size");
|
||||
#endif
|
||||
|
||||
SystemInterface() : data(nullptr) {}
|
||||
explicit operator bool() { return data; }
|
||||
|
||||
#ifdef _WIN32
|
||||
SystemInterface(lib_t handle, const char* name) : data(GetProcAddress(handle, name)) {}
|
||||
#else
|
||||
SystemInterface(lib_t handle, const char* name) : data(dlsym(handle, name)) {}
|
||||
#endif
|
||||
};
|
||||
#endif //PLUGINSYSTEM3_SYSTEMINTERFACE_HPP
|
@ -1,113 +0,0 @@
|
||||
//
|
||||
// Created by koncord on 23.01.16.
|
||||
//
|
||||
|
||||
#ifndef TMPTYPES_HPP
|
||||
#define TMPTYPES_HPP
|
||||
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <type_traits>
|
||||
#include <RakNetTypes.h>
|
||||
#include "Utils.hpp"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
typedef HMODULE lib_t;
|
||||
#else
|
||||
typedef void* lib_t;
|
||||
#endif
|
||||
|
||||
template<typename T> struct sizeof_void { enum { value = sizeof(T) }; };
|
||||
template<> struct sizeof_void<void> { enum { value = 0 }; };
|
||||
|
||||
|
||||
template<typename T, size_t t> struct TypeChar { static_assert(!t, "Unsupported type in variadic type list"); };
|
||||
template<> struct TypeChar<bool, sizeof(bool)> { enum { value = 'b' }; };
|
||||
template<typename T> struct TypeChar<T*, sizeof(void*)> { enum { value = 'p' }; };
|
||||
template<> struct TypeChar<double*, sizeof(double*)> { enum { value = 'd' }; };
|
||||
template<> struct TypeChar<RakNet::NetworkID**, sizeof(RakNet::NetworkID**)> { enum { value = 'n' }; };
|
||||
template<typename T> struct TypeChar<T, sizeof(uint8_t)> { enum { value = std::is_signed<T>::value ? 'q' : 'i' }; };
|
||||
template<typename T> struct TypeChar<T, sizeof(uint16_t)> { enum { value = std::is_signed<T>::value ? 'q' : 'i' }; };
|
||||
template<typename T> struct TypeChar<T, sizeof(uint32_t)> { enum { value = std::is_signed<T>::value ? 'q' : 'i' }; };
|
||||
template<typename T> struct TypeChar<T, sizeof(uint64_t)> { enum { value = std::is_signed<T>::value ? 'w' : 'l' }; };
|
||||
template<> struct TypeChar<double, sizeof(double)> { enum { value = 'f' }; };
|
||||
template<> struct TypeChar<char*, sizeof(char*)> { enum { value = 's' }; };
|
||||
template<> struct TypeChar<const char*, sizeof(const char*)> { enum { value = 's' }; };
|
||||
template<> struct TypeChar<void, sizeof_void<void>::value> { enum { value = 'v' }; };
|
||||
|
||||
template<const char t> struct CharType { static_assert(!t, "Unsupported type in variadic type list"); };
|
||||
template<> struct CharType<'b'> { typedef bool type; };
|
||||
template<> struct CharType<'p'> { typedef void* type; };
|
||||
template<> struct CharType<'d'> { typedef double* type; };
|
||||
template<> struct CharType<'n'> { typedef RakNet::NetworkID** type; };
|
||||
template<> struct CharType<'q'> { typedef signed int type; };
|
||||
template<> struct CharType<'i'> { typedef unsigned int type; };
|
||||
template<> struct CharType<'w'> { typedef signed long long type; };
|
||||
template<> struct CharType<'l'> { typedef unsigned long long type; };
|
||||
template<> struct CharType<'f'> { typedef double type; };
|
||||
template<> struct CharType<'s'> { typedef const char* type; };
|
||||
template<> struct CharType<'v'> { typedef void type; };
|
||||
|
||||
template<typename... Types>
|
||||
struct TypeString {
|
||||
static constexpr char value[sizeof...(Types) + 1] = {
|
||||
TypeChar<Types, sizeof(Types)>::value...
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
template<typename R, typename... Types>
|
||||
using Function = R(*)(Types...);
|
||||
|
||||
template<typename R>
|
||||
using FunctionEllipsis = R(*)(...);
|
||||
|
||||
struct ScriptIdentity
|
||||
{
|
||||
const char* types;
|
||||
const char ret;
|
||||
const unsigned int numargs;
|
||||
|
||||
constexpr bool matches(const char* types, const unsigned int N = 0) const
|
||||
{
|
||||
return N < numargs ? this->types[N] == types[N] && matches(types, N + 1) : this->types[N] == types[N];
|
||||
}
|
||||
|
||||
template<typename R, typename... Types>
|
||||
constexpr ScriptIdentity(Function<R, Types...>) : types(TypeString<Types...>::value), ret(TypeChar<R, sizeof_void<R>::value>::value), numargs(sizeof(TypeString<Types...>::value) - 1) {}
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct ScriptFunctionPointer : public ScriptIdentity
|
||||
{
|
||||
Function<void> addr;
|
||||
|
||||
template<typename R, typename... Types>
|
||||
constexpr ScriptFunctionPointer(Function<R, Types...> addr) : ScriptIdentity(addr), addr(reinterpret_cast<Function<void>>(addr)) {}
|
||||
};
|
||||
|
||||
struct ScriptFunctionData
|
||||
{
|
||||
const char* name;
|
||||
const ScriptFunctionPointer func;
|
||||
|
||||
constexpr ScriptFunctionData(const char* name, ScriptFunctionPointer func) : name(name), func(func) {}
|
||||
};
|
||||
|
||||
struct ScriptCallbackData
|
||||
{
|
||||
const char* name;
|
||||
const unsigned int index;
|
||||
const ScriptIdentity callback;
|
||||
|
||||
template<size_t N>
|
||||
constexpr ScriptCallbackData(const char(&name)[N], ScriptIdentity _callback) : name(name), index(Utils::hash(name)), callback(_callback) {}
|
||||
};
|
||||
|
||||
#endif //TMPTYPES_HPP
|
@ -0,0 +1,31 @@
|
||||
//
|
||||
// Created by koncord on 03.08.17.
|
||||
//
|
||||
|
||||
#include <boost/tokenizer.hpp>
|
||||
#include "luaUtils.hpp"
|
||||
#include "LuaState.hpp"
|
||||
|
||||
sol::table str_split(const std::string &str, const sol::object &sepObj, sol::this_state state)
|
||||
{
|
||||
sol::state_view lua(state);
|
||||
sol::table tbl = lua.create_table();
|
||||
|
||||
typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
|
||||
boost::char_separator<char> sep(sepObj.valid() ? sepObj.as<const char *>() : ":");
|
||||
tokenizer tokens(str, sep);
|
||||
|
||||
for (const auto &token : tokens)
|
||||
tbl.add(token);
|
||||
|
||||
return tbl;
|
||||
}
|
||||
|
||||
void LuaUtils::Init(LuaState &lua)
|
||||
{
|
||||
sol::table strTable = (*lua.getState())["string"];
|
||||
if (!strTable.valid())
|
||||
throw std::runtime_error("string library not initialized");
|
||||
|
||||
strTable.set_function("split", &str_split);
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
//
|
||||
// Created by koncord on 03.08.17.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Utils.hpp"
|
||||
|
||||
#include "sol.hpp"
|
||||
|
||||
class LuaState;
|
||||
|
||||
class LuaUtils
|
||||
{
|
||||
//Singleton(LuaUtils)
|
||||
public:
|
||||
static void Init(LuaState &lua);
|
||||
};
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue