commit newest tfs branch only for compare

This commit is contained in:
ErikasKontenis
2020-01-02 19:39:21 +02:00
parent 0b0624a20b
commit 1f7dcd7347
160 changed files with 24900 additions and 10996 deletions

View File

@@ -1,6 +1,6 @@
/**
* Tibia GIMUD Server - a free and open-source MMORPG server emulator
* Copyright (C) 2019 Sabrehaven and Mark Samman <mark.samman@gmail.com>
* The Forgotten Server - a free and open-source MMORPG server emulator
* Copyright (C) 2019 Mark Samman <mark.samman@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -36,43 +36,49 @@ MoveEvents::MoveEvents() :
MoveEvents::~MoveEvents()
{
clear();
clear(false);
}
void MoveEvents::clearMap(MoveListMap& map)
void MoveEvents::clearMap(MoveListMap& map, bool fromLua)
{
std::unordered_set<MoveEvent*> set;
for (const auto& it : map) {
const MoveEventList& moveEventList = it.second;
for (const auto& i : moveEventList.moveEvent) {
for (MoveEvent* moveEvent : i) {
set.insert(moveEvent);
for (auto it = map.begin(); it != map.end(); ++it) {
for (int eventType = MOVE_EVENT_STEP_IN; eventType < MOVE_EVENT_LAST; ++eventType) {
auto& moveEvents = it->second.moveEvent[eventType];
for (auto find = moveEvents.begin(); find != moveEvents.end(); ) {
if (fromLua == find->fromLua) {
find = moveEvents.erase(find);
} else {
++find;
}
}
}
}
map.clear();
for (MoveEvent* moveEvent : set) {
delete moveEvent;
}
}
void MoveEvents::clear()
void MoveEvents::clearPosMap(MovePosListMap& map, bool fromLua)
{
clearMap(itemIdMap);
clearMap(movementIdMap);
for (const auto& it : positionMap) {
const MoveEventList& moveEventList = it.second;
for (const auto& i : moveEventList.moveEvent) {
for (MoveEvent* moveEvent : i) {
delete moveEvent;
for (auto it = map.begin(); it != map.end(); ++it) {
for (int eventType = MOVE_EVENT_STEP_IN; eventType < MOVE_EVENT_LAST; ++eventType) {
auto& moveEvents = it->second.moveEvent[eventType];
for (auto find = moveEvents.begin(); find != moveEvents.end(); ) {
if (fromLua == find->fromLua) {
find = moveEvents.erase(find);
} else {
++find;
}
}
}
}
positionMap.clear();
}
scriptInterface.reInitState();
void MoveEvents::clear(bool fromLua)
{
clearMap(itemIdMap, fromLua);
clearMap(actionIdMap, fromLua);
clearMap(uniqueIdMap, fromLua);
clearPosMap(positionMap, fromLua);
reInitState(fromLua);
}
LuaScriptInterface& MoveEvents::getScriptInterface()
@@ -85,17 +91,17 @@ std::string MoveEvents::getScriptBaseName() const
return "movements";
}
Event* MoveEvents::getEvent(const std::string& nodeName)
Event_ptr MoveEvents::getEvent(const std::string& nodeName)
{
if (strcasecmp(nodeName.c_str(), "movevent") != 0) {
return nullptr;
}
return new MoveEvent(&scriptInterface);
return Event_ptr(new MoveEvent(&scriptInterface));
}
bool MoveEvents::registerEvent(Event* event, const pugi::xml_node& node)
bool MoveEvents::registerEvent(Event_ptr event, const pugi::xml_node& node)
{
MoveEvent* moveEvent = static_cast<MoveEvent*>(event); //event is guaranteed to be a MoveEvent
MoveEvent_ptr moveEvent{static_cast<MoveEvent*>(event.release())}; //event is guaranteed to be a MoveEvent
const MoveEvent_t eventType = moveEvent->getEventType();
if (eventType == MOVE_EVENT_ADD_ITEM || eventType == MOVE_EVENT_REMOVE_ITEM) {
@@ -117,7 +123,6 @@ bool MoveEvents::registerEvent(Event* event, const pugi::xml_node& node)
pugi::xml_attribute attr;
if ((attr = node.attribute("itemid"))) {
int32_t id = pugi::cast<int32_t>(attr.value());
addEvent(moveEvent, id, itemIdMap);
if (moveEvent->getEventType() == MOVE_EVENT_EQUIP) {
ItemType& it = Item::items.getItemType(id);
it.wieldInfo = moveEvent->getWieldInfo();
@@ -125,11 +130,12 @@ bool MoveEvents::registerEvent(Event* event, const pugi::xml_node& node)
it.minReqMagicLevel = moveEvent->getReqMagLv();
it.vocationString = moveEvent->getVocationString();
}
addEvent(std::move(*moveEvent), id, itemIdMap);
} else if ((attr = node.attribute("fromid"))) {
uint32_t id = pugi::cast<uint32_t>(attr.value());
uint32_t endId = pugi::cast<uint32_t>(node.attribute("toid").value());
addEvent(moveEvent, id, itemIdMap);
addEvent(*moveEvent, id, itemIdMap);
if (moveEvent->getEventType() == MOVE_EVENT_EQUIP) {
ItemType& it = Item::items.getItemType(id);
@@ -139,7 +145,7 @@ bool MoveEvents::registerEvent(Event* event, const pugi::xml_node& node)
it.vocationString = moveEvent->getVocationString();
while (++id <= endId) {
addEvent(moveEvent, id, itemIdMap);
addEvent(*moveEvent, id, itemIdMap);
ItemType& tit = Item::items.getItemType(id);
tit.wieldInfo = moveEvent->getWieldInfo();
@@ -149,17 +155,26 @@ bool MoveEvents::registerEvent(Event* event, const pugi::xml_node& node)
}
} else {
while (++id <= endId) {
addEvent(moveEvent, id, itemIdMap);
addEvent(*moveEvent, id, itemIdMap);
}
}
} else if ((attr = node.attribute("movementid"))) {
addEvent(moveEvent, pugi::cast<int32_t>(attr.value()), movementIdMap);
} else if ((attr = node.attribute("frommovementid"))) {
} else if ((attr = node.attribute("uniqueid"))) {
addEvent(std::move(*moveEvent), pugi::cast<int32_t>(attr.value()), uniqueIdMap);
} else if ((attr = node.attribute("fromuid"))) {
uint32_t id = pugi::cast<uint32_t>(attr.value());
uint32_t endId = pugi::cast<uint32_t>(node.attribute("tomovementid").value());
addEvent(moveEvent, id, movementIdMap);
uint32_t endId = pugi::cast<uint32_t>(node.attribute("touid").value());
addEvent(*moveEvent, id, uniqueIdMap);
while (++id <= endId) {
addEvent(moveEvent, id, movementIdMap);
addEvent(*moveEvent, id, uniqueIdMap);
}
} else if ((attr = node.attribute("actionid"))) {
addEvent(std::move(*moveEvent), pugi::cast<int32_t>(attr.value()), actionIdMap);
} else if ((attr = node.attribute("fromaid"))) {
uint32_t id = pugi::cast<uint32_t>(attr.value());
uint32_t endId = pugi::cast<uint32_t>(node.attribute("toaid").value());
addEvent(*moveEvent, id, actionIdMap);
while (++id <= endId) {
addEvent(*moveEvent, id, actionIdMap);
}
} else if ((attr = node.attribute("pos"))) {
std::vector<int32_t> posList = vectorAtoi(explodeString(attr.as_string(), ";"));
@@ -168,28 +183,125 @@ bool MoveEvents::registerEvent(Event* event, const pugi::xml_node& node)
}
Position pos(posList[0], posList[1], posList[2]);
addEvent(moveEvent, pos, positionMap);
addEvent(std::move(*moveEvent), pos, positionMap);
} else {
return false;
}
return true;
}
void MoveEvents::addEvent(MoveEvent* moveEvent, int32_t id, MoveListMap& map)
bool MoveEvents::registerLuaFunction(MoveEvent* event)
{
MoveEvent_ptr moveEvent{ event };
if (moveEvent->getItemIdRange().size() > 0) {
if (moveEvent->getItemIdRange().size() == 1) {
uint32_t id = moveEvent->getItemIdRange().at(0);
addEvent(*moveEvent, id, itemIdMap);
if (moveEvent->getEventType() == MOVE_EVENT_EQUIP) {
ItemType& it = Item::items.getItemType(id);
it.wieldInfo = moveEvent->getWieldInfo();
it.minReqLevel = moveEvent->getReqLevel();
it.minReqMagicLevel = moveEvent->getReqMagLv();
it.vocationString = moveEvent->getVocationString();
}
} else {
uint32_t iterId = 0;
while (++iterId < moveEvent->getItemIdRange().size()) {
if (moveEvent->getEventType() == MOVE_EVENT_EQUIP) {
ItemType& it = Item::items.getItemType(moveEvent->getItemIdRange().at(iterId));
it.wieldInfo = moveEvent->getWieldInfo();
it.minReqLevel = moveEvent->getReqLevel();
it.minReqMagicLevel = moveEvent->getReqMagLv();
it.vocationString = moveEvent->getVocationString();
}
addEvent(*moveEvent, moveEvent->getItemIdRange().at(iterId), itemIdMap);
}
}
} else {
return false;
}
return true;
}
bool MoveEvents::registerLuaEvent(MoveEvent* event)
{
MoveEvent_ptr moveEvent{ event };
if (moveEvent->getItemIdRange().size() > 0) {
if (moveEvent->getItemIdRange().size() == 1) {
uint32_t id = moveEvent->getItemIdRange().at(0);
addEvent(*moveEvent, id, itemIdMap);
if (moveEvent->getEventType() == MOVE_EVENT_EQUIP) {
ItemType& it = Item::items.getItemType(id);
it.wieldInfo = moveEvent->getWieldInfo();
it.minReqLevel = moveEvent->getReqLevel();
it.minReqMagicLevel = moveEvent->getReqMagLv();
it.vocationString = moveEvent->getVocationString();
}
} else {
auto v = moveEvent->getItemIdRange();
for (auto i = v.begin(); i != v.end(); i++) {
if (moveEvent->getEventType() == MOVE_EVENT_EQUIP) {
ItemType& it = Item::items.getItemType(*i);
it.wieldInfo = moveEvent->getWieldInfo();
it.minReqLevel = moveEvent->getReqLevel();
it.minReqMagicLevel = moveEvent->getReqMagLv();
it.vocationString = moveEvent->getVocationString();
}
addEvent(*moveEvent, *i, itemIdMap);
}
}
} else if (moveEvent->getActionIdRange().size() > 0) {
if (moveEvent->getActionIdRange().size() == 1) {
int32_t id = moveEvent->getActionIdRange().at(0);
addEvent(*moveEvent, id, actionIdMap);
} else {
auto v = moveEvent->getActionIdRange();
for (auto i = v.begin(); i != v.end(); i++) {
addEvent(*moveEvent, *i, actionIdMap);
}
}
} else if (moveEvent->getUniqueIdRange().size() > 0) {
if (moveEvent->getUniqueIdRange().size() == 1) {
int32_t id = moveEvent->getUniqueIdRange().at(0);
addEvent(*moveEvent, id, uniqueIdMap);
} else {
auto v = moveEvent->getUniqueIdRange();
for (auto i = v.begin(); i != v.end(); i++) {
addEvent(*moveEvent, *i, uniqueIdMap);
}
}
} else if (moveEvent->getPosList().size() > 0) {
if (moveEvent->getPosList().size() == 1) {
Position pos = moveEvent->getPosList().at(0);
addEvent(*moveEvent, pos, positionMap);
} else {
auto v = moveEvent->getPosList();
for (auto i = v.begin(); i != v.end(); i++) {
addEvent(*moveEvent, *i, positionMap);
}
}
} else {
return false;
}
return true;
}
void MoveEvents::addEvent(MoveEvent moveEvent, int32_t id, MoveListMap& map)
{
auto it = map.find(id);
if (it == map.end()) {
MoveEventList moveEventList;
moveEventList.moveEvent[moveEvent->getEventType()].push_back(moveEvent);
moveEventList.moveEvent[moveEvent.getEventType()].push_back(std::move(moveEvent));
map[id] = moveEventList;
} else {
std::list<MoveEvent*>& moveEventList = it->second.moveEvent[moveEvent->getEventType()];
for (MoveEvent* existingMoveEvent : moveEventList) {
if (existingMoveEvent->getSlot() == moveEvent->getSlot()) {
std::list<MoveEvent>& moveEventList = it->second.moveEvent[moveEvent.getEventType()];
for (MoveEvent& existingMoveEvent : moveEventList) {
if (existingMoveEvent.getSlot() == moveEvent.getSlot()) {
std::cout << "[Warning - MoveEvents::addEvent] Duplicate move event found: " << id << std::endl;
}
}
moveEventList.push_back(moveEvent);
moveEventList.push_back(std::move(moveEvent));
}
}
@@ -212,59 +324,64 @@ MoveEvent* MoveEvents::getEvent(Item* item, MoveEvent_t eventType, slots_t slot)
auto it = itemIdMap.find(item->getID());
if (it != itemIdMap.end()) {
std::list<MoveEvent*>& moveEventList = it->second.moveEvent[eventType];
for (MoveEvent* moveEvent : moveEventList) {
if ((moveEvent->getSlot() & slotp) != 0) {
return moveEvent;
std::list<MoveEvent>& moveEventList = it->second.moveEvent[eventType];
for (MoveEvent& moveEvent : moveEventList) {
if ((moveEvent.getSlot() & slotp) != 0) {
return &moveEvent;
}
}
}
return nullptr;
}
MoveEvent* MoveEvents::getEvent(Item* item, MoveEvent_t eventType)
MoveEvent* MoveEvents::getEvent(Item* item, MoveEvent_t eventType)
{
MoveListMap::iterator it;
if (item->hasAttribute(ITEM_ATTRIBUTE_MOVEMENTID)) {
it = movementIdMap.find(item->getMovementId());
if (it != movementIdMap.end()) {
std::list<MoveEvent*>& moveEventList = it->second.moveEvent[eventType];
if (item->hasAttribute(ITEM_ATTRIBUTE_UNIQUEID)) {
it = uniqueIdMap.find(item->getUniqueId());
if (it != uniqueIdMap.end()) {
std::list<MoveEvent>& moveEventList = it->second.moveEvent[eventType];
if (!moveEventList.empty()) {
return *moveEventList.begin();
return &(*moveEventList.begin());
}
}
}
if (!item->hasCollisionEvent() && !item->hasSeparationEvent()) {
return nullptr;
if (item->hasAttribute(ITEM_ATTRIBUTE_ACTIONID)) {
it = actionIdMap.find(item->getActionId());
if (it != actionIdMap.end()) {
std::list<MoveEvent>& moveEventList = it->second.moveEvent[eventType];
if (!moveEventList.empty()) {
return &(*moveEventList.begin());
}
}
}
it = itemIdMap.find(item->getID());
if (it != itemIdMap.end()) {
std::list<MoveEvent*>& moveEventList = it->second.moveEvent[eventType];
std::list<MoveEvent>& moveEventList = it->second.moveEvent[eventType];
if (!moveEventList.empty()) {
return *moveEventList.begin();
return &(*moveEventList.begin());
}
}
return nullptr;
}
void MoveEvents::addEvent(MoveEvent* moveEvent, const Position& pos, MovePosListMap& map)
void MoveEvents::addEvent(MoveEvent moveEvent, const Position& pos, MovePosListMap& map)
{
auto it = map.find(pos);
if (it == map.end()) {
MoveEventList moveEventList;
moveEventList.moveEvent[moveEvent->getEventType()].push_back(moveEvent);
moveEventList.moveEvent[moveEvent.getEventType()].push_back(std::move(moveEvent));
map[pos] = moveEventList;
} else {
std::list<MoveEvent*>& moveEventList = it->second.moveEvent[moveEvent->getEventType()];
std::list<MoveEvent>& moveEventList = it->second.moveEvent[moveEvent.getEventType()];
if (!moveEventList.empty()) {
std::cout << "[Warning - MoveEvents::addEvent] Duplicate move event found: " << pos << std::endl;
}
moveEventList.push_back(moveEvent);
moveEventList.push_back(std::move(moveEvent));
}
}
@@ -272,9 +389,9 @@ MoveEvent* MoveEvents::getEvent(const Tile* tile, MoveEvent_t eventType)
{
auto it = positionMap.find(tile->getPosition());
if (it != positionMap.end()) {
std::list<MoveEvent*>& moveEventList = it->second.moveEvent[eventType];
std::list<MoveEvent>& moveEventList = it->second.moveEvent[eventType];
if (!moveEventList.empty()) {
return *moveEventList.begin();
return &(*moveEventList.begin());
}
}
return nullptr;
@@ -325,7 +442,7 @@ uint32_t MoveEvents::onPlayerDeEquip(Player* player, Item* item, slots_t slot)
if (!moveEvent) {
return 1;
}
return moveEvent->fireEquip(player, item, slot, true);
return moveEvent->fireEquip(player, item, slot, false);
}
uint32_t MoveEvents::onItemMove(Item* item, Tile* tile, bool isAdd)
@@ -371,20 +488,6 @@ uint32_t MoveEvents::onItemMove(Item* item, Tile* tile, bool isAdd)
MoveEvent::MoveEvent(LuaScriptInterface* interface) : Event(interface) {}
MoveEvent::MoveEvent(const MoveEvent* copy) :
Event(copy),
eventType(copy->eventType),
stepFunction(copy->stepFunction),
moveFunction(copy->moveFunction),
equipFunction(copy->equipFunction),
slot(copy->slot),
reqLevel(copy->reqLevel),
reqMagLevel(copy->reqMagLevel),
premium(copy->premium),
vocationString(copy->vocationString),
wieldInfo(copy->wieldInfo),
vocEquipMap(copy->vocEquipMap) {}
std::string MoveEvent::getScriptEventName() const
{
switch (eventType) {
@@ -521,40 +624,6 @@ bool MoveEvent::configureEvent(const pugi::xml_node& node)
return true;
}
bool MoveEvent::loadFunction(const pugi::xml_attribute& attr)
{
const char* functionName = attr.as_string();
if (strcasecmp(functionName, "onstepinfield") == 0) {
stepFunction = StepInField;
} else if (strcasecmp(functionName, "onstepoutfield") == 0) {
stepFunction = StepOutField;
} else if (strcasecmp(functionName, "onaddfield") == 0) {
moveFunction = AddItemField;
} else if (strcasecmp(functionName, "onremovefield") == 0) {
moveFunction = RemoveItemField;
} else if (strcasecmp(functionName, "onequipitem") == 0) {
equipFunction = EquipItem;
} else if (strcasecmp(functionName, "ondeequipitem") == 0) {
equipFunction = DeEquipItem;
} else {
std::cout << "[Warning - MoveEvent::loadFunction] Function \"" << functionName << "\" does not exist." << std::endl;
return false;
}
scripted = false;
return true;
}
MoveEvent_t MoveEvent::getEventType() const
{
return eventType;
}
void MoveEvent::setEventType(MoveEvent_t type)
{
eventType = type;
}
uint32_t MoveEvent::StepInField(Creature* creature, Item* item, const Position&)
{
MagicField* field = item->getMagicField();
@@ -646,10 +715,6 @@ uint32_t MoveEvent::EquipItem(MoveEvent* moveEvent, Player* player, Item* item,
player->sendIcons();
}
if (it.abilities->absorbPercent[combatTypeToIndex(COMBAT_DROWNDAMAGE)] == 100) {
player->removeCondition(CONDITION_DROWN);
}
if (it.abilities->regeneration) {
Condition* condition = Condition::createCondition(static_cast<ConditionId_t>(slot), CONDITION_REGENERATION, -1, 0);
@@ -682,6 +747,13 @@ uint32_t MoveEvent::EquipItem(MoveEvent* moveEvent, Player* player, Item* item,
}
}
for (int32_t i = SPECIALSKILL_FIRST; i <= SPECIALSKILL_LAST; ++i) {
if (it.abilities->specialSkills[i]) {
needUpdateSkills = true;
player->setVarSpecialSkill(static_cast<SpecialSkills_t>(i), it.abilities->specialSkills[i]);
}
}
if (needUpdateSkills) {
player->sendSkills();
}
@@ -757,6 +829,13 @@ uint32_t MoveEvent::DeEquipItem(MoveEvent*, Player* player, Item* item, slots_t
}
}
for (int32_t i = SPECIALSKILL_FIRST; i <= SPECIALSKILL_LAST; ++i) {
if (it.abilities->specialSkills[i] != 0) {
needUpdateSkills = true;
player->setVarSpecialSkill(static_cast<SpecialSkills_t>(i), -it.abilities->specialSkills[i]);
}
}
if (needUpdateSkills) {
player->sendSkills();
}
@@ -783,6 +862,44 @@ uint32_t MoveEvent::DeEquipItem(MoveEvent*, Player* player, Item* item, slots_t
return 1;
}
bool MoveEvent::loadFunction(const pugi::xml_attribute& attr, bool isScripted)
{
const char* functionName = attr.as_string();
if (strcasecmp(functionName, "onstepinfield") == 0) {
stepFunction = StepInField;
} else if (strcasecmp(functionName, "onstepoutfield") == 0) {
stepFunction = StepOutField;
} else if (strcasecmp(functionName, "onaddfield") == 0) {
moveFunction = AddItemField;
} else if (strcasecmp(functionName, "onremovefield") == 0) {
moveFunction = RemoveItemField;
} else if (strcasecmp(functionName, "onequipitem") == 0) {
equipFunction = EquipItem;
} else if (strcasecmp(functionName, "ondeequipitem") == 0) {
equipFunction = DeEquipItem;
} else {
if (!isScripted) {
std::cout << "[Warning - MoveEvent::loadFunction] Function \"" << functionName << "\" does not exist." << std::endl;
return false;
}
}
if (!isScripted) {
scripted = false;
}
return true;
}
MoveEvent_t MoveEvent::getEventType() const
{
return eventType;
}
void MoveEvent::setEventType(MoveEvent_t type)
{
eventType = type;
}
uint32_t MoveEvent::fireStepEvent(Creature* creature, Item* item, const Position& pos)
{
if (scripted) {
@@ -816,19 +933,24 @@ bool MoveEvent::executeStep(Creature* creature, Item* item, const Position& pos)
return scriptInterface->callFunction(4);
}
uint32_t MoveEvent::fireEquip(Player* player, Item* item, slots_t slot, bool boolean)
uint32_t MoveEvent::fireEquip(Player* player, Item* item, slots_t slot, bool isCheck)
{
if (scripted) {
return executeEquip(player, item, slot);
if (!equipFunction || equipFunction(this, player, item, slot, isCheck) == 1) {
if (executeEquip(player, item, slot, isCheck)) {
return 1;
}
}
return 0;
} else {
return equipFunction(this, player, item, slot, boolean);
return equipFunction(this, player, item, slot, isCheck);
}
}
bool MoveEvent::executeEquip(Player* player, Item* item, slots_t slot)
bool MoveEvent::executeEquip(Player* player, Item* item, slots_t slot, bool isCheck)
{
//onEquip(player, item, slot)
//onDeEquip(player, item, slot)
//onEquip(player, item, slot, isCheck)
//onDeEquip(player, item, slot, isCheck)
if (!scriptInterface->reserveScriptEnv()) {
std::cout << "[Error - MoveEvent::executeEquip] Call stack overflow" << std::endl;
return false;
@@ -844,8 +966,9 @@ bool MoveEvent::executeEquip(Player* player, Item* item, slots_t slot)
LuaScriptInterface::setMetatable(L, -1, "Player");
LuaScriptInterface::pushThing(L, item);
lua_pushnumber(L, slot);
LuaScriptInterface::pushBoolean(L, isCheck);
return scriptInterface->callFunction(3);
return scriptInterface->callFunction(4);
}
uint32_t MoveEvent::fireAddRemItem(Item* item, Item* tileItem, const Position& pos)