mirror of
https://github.com/EQEmu/Server.git
synced 2026-03-06 02:02:25 +00:00
Merge branch 'master' into shared_tasks
This commit is contained in:
commit
8934235030
23
.editorconfig
Normal file
23
.editorconfig
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# EditorConfig is awesome: http://EditorConfig.org
|
||||||
|
|
||||||
|
# top-most EditorConfig file
|
||||||
|
root = true
|
||||||
|
|
||||||
|
# Unix-style newlines with a newline ending every file
|
||||||
|
[*]
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = true
|
||||||
|
|
||||||
|
# Matches multiple files with brace expansion notation
|
||||||
|
# Set default charset
|
||||||
|
[*.{js,py}]
|
||||||
|
charset = utf-8
|
||||||
|
|
||||||
|
[*.cpp]
|
||||||
|
indent_style = tab
|
||||||
|
[*.h]
|
||||||
|
indent_style = tab
|
||||||
|
|
||||||
|
# Tab indentation (no size specified)
|
||||||
|
[Makefile]
|
||||||
|
indent_style = tab
|
||||||
@ -28,6 +28,9 @@
|
|||||||
#EQEMU_MAP_DIR
|
#EQEMU_MAP_DIR
|
||||||
|
|
||||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||||
|
IF(POLICY CMP0074)
|
||||||
|
cmake_policy(SET CMP0074 NEW)
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
#FindMySQL is located here so lets make it so CMake can find it
|
#FindMySQL is located here so lets make it so CMake can find it
|
||||||
SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/" ${CMAKE_MODULE_PATH})
|
SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/" ${CMAKE_MODULE_PATH})
|
||||||
|
|||||||
@ -702,6 +702,7 @@ RULE_CATEGORY_END()
|
|||||||
RULE_CATEGORY(QueryServ)
|
RULE_CATEGORY(QueryServ)
|
||||||
RULE_BOOL(QueryServ, PlayerLogChat, false) // Logs Player Chat
|
RULE_BOOL(QueryServ, PlayerLogChat, false) // Logs Player Chat
|
||||||
RULE_BOOL(QueryServ, PlayerLogTrades, false) // Logs Player Trades
|
RULE_BOOL(QueryServ, PlayerLogTrades, false) // Logs Player Trades
|
||||||
|
RULE_BOOL(QueryServ, PlayerDropItems, false) // Logs Player dropping items
|
||||||
RULE_BOOL(QueryServ, PlayerLogHandins, false) // Logs Player Handins
|
RULE_BOOL(QueryServ, PlayerLogHandins, false) // Logs Player Handins
|
||||||
RULE_BOOL(QueryServ, PlayerLogNPCKills, false) // Logs Player NPC Kills
|
RULE_BOOL(QueryServ, PlayerLogNPCKills, false) // Logs Player NPC Kills
|
||||||
RULE_BOOL(QueryServ, PlayerLogDeletes, false) // Logs Player Deletes
|
RULE_BOOL(QueryServ, PlayerLogDeletes, false) // Logs Player Deletes
|
||||||
|
|||||||
@ -210,6 +210,7 @@
|
|||||||
#define ServerOP_CZSignalNPC 0x5017
|
#define ServerOP_CZSignalNPC 0x5017
|
||||||
#define ServerOP_CZSetEntityVariableByNPCTypeID 0x5018
|
#define ServerOP_CZSetEntityVariableByNPCTypeID 0x5018
|
||||||
#define ServerOP_WWMarquee 0x5019
|
#define ServerOP_WWMarquee 0x5019
|
||||||
|
#define ServerOP_QSPlayerDropItem 0x5020
|
||||||
|
|
||||||
/* Query Serv Generic Packet Flag/Type Enumeration */
|
/* Query Serv Generic Packet Flag/Type Enumeration */
|
||||||
enum { QSG_LFGuild = 0 };
|
enum { QSG_LFGuild = 0 };
|
||||||
@ -1160,6 +1161,27 @@ struct QSPlayerLogTrade_Struct {
|
|||||||
QSTradeItems_Struct items[0];
|
QSTradeItems_Struct items[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct QSDropItems_Struct {
|
||||||
|
uint32 item_id;
|
||||||
|
uint16 charges;
|
||||||
|
uint32 aug_1;
|
||||||
|
uint32 aug_2;
|
||||||
|
uint32 aug_3;
|
||||||
|
uint32 aug_4;
|
||||||
|
uint32 aug_5;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct QSPlayerDropItem_Struct {
|
||||||
|
uint32 char_id;
|
||||||
|
bool pickup; // 0 drop, 1 pickup
|
||||||
|
uint32 zone_id;
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
|
int z;
|
||||||
|
uint16 _detail_count;
|
||||||
|
QSDropItems_Struct items[0];
|
||||||
|
};
|
||||||
|
|
||||||
struct QSHandinItems_Struct {
|
struct QSHandinItems_Struct {
|
||||||
char action_type[7]; // handin, return or reward
|
char action_type[7]; // handin, return or reward
|
||||||
uint16 char_slot;
|
uint16 char_slot;
|
||||||
|
|||||||
@ -123,6 +123,39 @@ void Database::AddSpeech(const char* from, const char* to, const char* message,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Database::LogPlayerDropItem(QSPlayerDropItem_Struct* QS) {
|
||||||
|
|
||||||
|
std::string query = StringFormat("INSERT INTO `qs_player_drop_record` SET `time` = NOW(), "
|
||||||
|
"`char_id` = '%i', `pickup` = '%i', "
|
||||||
|
"`zone_id` = '%i', `x` = '%i', `y` = '%i', `z` = '%i' ",
|
||||||
|
QS->char_id, QS->pickup, QS->zone_id, QS->x, QS->y, QS->z);
|
||||||
|
|
||||||
|
auto results = QueryDatabase(query);
|
||||||
|
if (!results.Success()) {
|
||||||
|
Log(Logs::Detail, Logs::QS_Server, "Failed Drop Record Insert: %s", results.ErrorMessage().c_str());
|
||||||
|
Log(Logs::Detail, Logs::QS_Server, "%s", query.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (QS->_detail_count == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int lastIndex = results.LastInsertedID();
|
||||||
|
|
||||||
|
for (int i = 0; i < QS->_detail_count; i++) {
|
||||||
|
query = StringFormat("INSERT INTO `qs_player_drop_record_entries` SET `event_id` = '%i', "
|
||||||
|
"`item_id` = '%i', `charges` = '%i', `aug_1` = '%i', `aug_2` = '%i', "
|
||||||
|
"`aug_3` = '%i', `aug_4` = '%i', `aug_5` = '%i'",
|
||||||
|
lastIndex, QS->items[i].item_id,
|
||||||
|
QS->items[i].charges, QS->items[i].aug_1, QS->items[i].aug_2,
|
||||||
|
QS->items[i].aug_3, QS->items[i].aug_4, QS->items[i].aug_5);
|
||||||
|
results = QueryDatabase(query);
|
||||||
|
if (!results.Success()) {
|
||||||
|
Log(Logs::Detail, Logs::QS_Server, "Failed Drop Record Entry Insert: %s", results.ErrorMessage().c_str());
|
||||||
|
Log(Logs::Detail, Logs::QS_Server, "%s", query.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Database::LogPlayerTrade(QSPlayerLogTrade_Struct* QS, uint32 detailCount) {
|
void Database::LogPlayerTrade(QSPlayerLogTrade_Struct* QS, uint32 detailCount) {
|
||||||
|
|
||||||
std::string query = StringFormat("INSERT INTO `qs_player_trade_record` SET `time` = NOW(), "
|
std::string query = StringFormat("INSERT INTO `qs_player_trade_record` SET `time` = NOW(), "
|
||||||
|
|||||||
@ -45,6 +45,7 @@ public:
|
|||||||
|
|
||||||
void AddSpeech(const char* from, const char* to, const char* message, uint16 minstatus, uint32 guilddbid, uint8 type);
|
void AddSpeech(const char* from, const char* to, const char* message, uint16 minstatus, uint32 guilddbid, uint8 type);
|
||||||
void LogPlayerTrade(QSPlayerLogTrade_Struct* QS, uint32 DetailCount);
|
void LogPlayerTrade(QSPlayerLogTrade_Struct* QS, uint32 DetailCount);
|
||||||
|
void LogPlayerDropItem(QSPlayerDropItem_Struct* QS);
|
||||||
void LogPlayerHandin(QSPlayerLogHandin_Struct* QS, uint32 DetailCount);
|
void LogPlayerHandin(QSPlayerLogHandin_Struct* QS, uint32 DetailCount);
|
||||||
void LogPlayerNPCKill(QSPlayerLogNPCKill_Struct* QS, uint32 Members);
|
void LogPlayerNPCKill(QSPlayerLogNPCKill_Struct* QS, uint32 Members);
|
||||||
void LogPlayerDelete(QSPlayerLogDelete_Struct* QS, uint32 Items);
|
void LogPlayerDelete(QSPlayerLogDelete_Struct* QS, uint32 Items);
|
||||||
|
|||||||
@ -98,6 +98,11 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p)
|
|||||||
database.LogPlayerTrade(QS, QS->_detail_count);
|
database.LogPlayerTrade(QS, QS->_detail_count);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case ServerOP_QSPlayerDropItem: {
|
||||||
|
QSPlayerDropItem_Struct *QS = (QSPlayerDropItem_Struct *) p.Data();
|
||||||
|
database.LogPlayerDropItem(QS);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case ServerOP_QSPlayerLogHandins: {
|
case ServerOP_QSPlayerLogHandins: {
|
||||||
QSPlayerLogHandin_Struct *QS = (QSPlayerLogHandin_Struct*)p.Data();
|
QSPlayerLogHandin_Struct *QS = (QSPlayerLogHandin_Struct*)p.Data();
|
||||||
database.LogPlayerHandin(QS, QS->_detail_count);
|
database.LogPlayerHandin(QS, QS->_detail_count);
|
||||||
|
|||||||
@ -530,6 +530,28 @@ void ClientList::SendWhoAll(uint32 fromid,const char* to, int16 admin, Who_All_S
|
|||||||
//uint32 x = 0;
|
//uint32 x = 0;
|
||||||
int whomlen = 0;
|
int whomlen = 0;
|
||||||
if (whom) {
|
if (whom) {
|
||||||
|
// fixes for client converting some queries into a race query instead of zone
|
||||||
|
if (whom->wrace == 221) {
|
||||||
|
whom->wrace = 0xFFFF;
|
||||||
|
strcpy(whom->whom, "scarlet");
|
||||||
|
}
|
||||||
|
if (whom->wrace == 327) {
|
||||||
|
whom->wrace = 0xFFFF;
|
||||||
|
strcpy(whom->whom, "crystal");
|
||||||
|
}
|
||||||
|
if (whom->wrace == 103) {
|
||||||
|
whom->wrace = 0xFFFF;
|
||||||
|
strcpy(whom->whom, "kedge");
|
||||||
|
}
|
||||||
|
if (whom->wrace == 230) {
|
||||||
|
whom->wrace = 0xFFFF;
|
||||||
|
strcpy(whom->whom, "akheva");
|
||||||
|
}
|
||||||
|
if (whom->wrace == 229) {
|
||||||
|
whom->wrace = 0xFFFF;
|
||||||
|
strcpy(whom->whom, "netherbian");
|
||||||
|
}
|
||||||
|
|
||||||
whomlen = strlen(whom->whom);
|
whomlen = strlen(whom->whom);
|
||||||
if(whom->wrace == 0x001A) // 0x001A is the old Froglok race number and is sent by the client for /who all froglok
|
if(whom->wrace == 0x001A) // 0x001A is the old Froglok race number and is sent by the client for /who all froglok
|
||||||
whom->wrace = FROGLOK; // This is what EQEmu uses for the Froglok Race number.
|
whom->wrace = FROGLOK; // This is what EQEmu uses for the Froglok Race number.
|
||||||
|
|||||||
@ -1297,6 +1297,7 @@ void ZoneServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) {
|
|||||||
case ServerOP_QSPlayerLogDeletes:
|
case ServerOP_QSPlayerLogDeletes:
|
||||||
case ServerOP_QSPlayerLogMoves:
|
case ServerOP_QSPlayerLogMoves:
|
||||||
case ServerOP_QSPlayerLogMerchantTransactions:
|
case ServerOP_QSPlayerLogMerchantTransactions:
|
||||||
|
case ServerOP_QSPlayerDropItem:
|
||||||
{
|
{
|
||||||
QSLink.SendPacket(pack);
|
QSLink.SendPacket(pack);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -885,6 +885,7 @@ public:
|
|||||||
void SetStats(uint8 type,int16 set_val);
|
void SetStats(uint8 type,int16 set_val);
|
||||||
void IncStats(uint8 type,int16 increase_val);
|
void IncStats(uint8 type,int16 increase_val);
|
||||||
void DropItem(int16 slot_id, bool recurse = true);
|
void DropItem(int16 slot_id, bool recurse = true);
|
||||||
|
void DropItemQS(EQEmu::ItemInstance* inst, bool pickup);
|
||||||
|
|
||||||
int GetItemLinkHash(const EQEmu::ItemInstance* inst); // move to ItemData..or make use of the pre-calculated database field
|
int GetItemLinkHash(const EQEmu::ItemInstance* inst); // move to ItemData..or make use of the pre-calculated database field
|
||||||
|
|
||||||
|
|||||||
@ -155,42 +155,43 @@ void Mob::ProcessFlee()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mob::CalculateNewFearpoint()
|
void Mob::CalculateNewFearpoint() {
|
||||||
{
|
if (RuleB(Pathing, Fear) && zone->pathing) {
|
||||||
if(RuleB(Pathing, Fear) && zone->pathing)
|
|
||||||
{
|
|
||||||
auto Node = zone->pathing->GetRandomLocation();
|
auto Node = zone->pathing->GetRandomLocation();
|
||||||
if (Node.x != 0.0f || Node.y != 0.0f || Node.z != 0.0f) {
|
if (Node.x != 0.0f || Node.y != 0.0f || Node.z != 0.0f) {
|
||||||
|
|
||||||
++Node.z;
|
++Node.z;
|
||||||
m_FearWalkTarget = Node;
|
m_FearWalkTarget = Node;
|
||||||
|
currently_fleeing = true;
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Log(Logs::Detail, Logs::None, "No path found to selected node. Falling through to old fear point selection.");
|
Log(Logs::Detail,
|
||||||
|
Logs::Pathing,
|
||||||
|
"No path found to selected node. Falling through to old fear point selection.");
|
||||||
}
|
}
|
||||||
|
|
||||||
int loop = 0;
|
int loop = 0;
|
||||||
float ranx, rany, ranz;
|
float ranx, rany, ranz;
|
||||||
|
|
||||||
currently_fleeing = true;
|
currently_fleeing = true;
|
||||||
while (loop < 100) //Max 100 tries
|
while (loop < 100) //Max 100 tries
|
||||||
{
|
{
|
||||||
int ran = 250 - (loop*2);
|
int ran = 250 - (loop * 2);
|
||||||
loop++;
|
loop++;
|
||||||
ranx = GetX()+zone->random.Int(0, ran-1)-zone->random.Int(0, ran-1);
|
ranx = GetX() + zone->random.Int(0, ran - 1) - zone->random.Int(0, ran - 1);
|
||||||
rany = GetY()+zone->random.Int(0, ran-1)-zone->random.Int(0, ran-1);
|
rany = GetY() + zone->random.Int(0, ran - 1) - zone->random.Int(0, ran - 1);
|
||||||
ranz = FindGroundZ(ranx,rany);
|
ranz = FindGroundZ(ranx, rany);
|
||||||
if (ranz == BEST_Z_INVALID)
|
if (ranz == BEST_Z_INVALID)
|
||||||
continue;
|
continue;
|
||||||
float fdist = ranz - GetZ();
|
float fdist = ranz - GetZ();
|
||||||
if (fdist >= -12 && fdist <= 12 && CheckCoordLosNoZLeaps(GetX(),GetY(),GetZ(),ranx,rany,ranz))
|
if (fdist >= -12 && fdist <= 12 && CheckCoordLosNoZLeaps(GetX(), GetY(), GetZ(), ranx, rany, ranz)) {
|
||||||
{
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currently_fleeing)
|
if (currently_fleeing)
|
||||||
m_FearWalkTarget = glm::vec3(ranx, rany, ranz);
|
m_FearWalkTarget = glm::vec3(ranx, rany, ranz);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -688,10 +688,79 @@ void Client::DropItem(int16 slot_id, bool recurse)
|
|||||||
object->StartDecay();
|
object->StartDecay();
|
||||||
|
|
||||||
Log(Logs::General, Logs::Inventory, "Item drop handled ut assolet");
|
Log(Logs::General, Logs::Inventory, "Item drop handled ut assolet");
|
||||||
|
DropItemQS(inst, false);
|
||||||
|
|
||||||
safe_delete(inst);
|
safe_delete(inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Client::DropItemQS(EQEmu::ItemInstance* inst, bool pickup) {
|
||||||
|
if (RuleB(QueryServ, PlayerDropItems)) {
|
||||||
|
QSPlayerDropItem_Struct qs_audit;
|
||||||
|
std::list<void*> event_details;
|
||||||
|
memset(&qs_audit, 0, sizeof(QSPlayerDropItem_Struct));
|
||||||
|
|
||||||
|
qs_audit.char_id = this->character_id;
|
||||||
|
qs_audit.pickup = pickup;
|
||||||
|
qs_audit.zone_id = this->GetZoneID();
|
||||||
|
qs_audit.x = (int) this->GetX();
|
||||||
|
qs_audit.y = (int) this->GetY();
|
||||||
|
qs_audit.z = (int) this->GetZ();
|
||||||
|
|
||||||
|
if (inst) {
|
||||||
|
auto detail = new QSDropItems_Struct;
|
||||||
|
detail->item_id = inst->GetID();
|
||||||
|
detail->charges = inst->IsClassBag() ? 1 : inst->GetCharges();
|
||||||
|
detail->aug_1 = inst->GetAugmentItemID(1);
|
||||||
|
detail->aug_2 = inst->GetAugmentItemID(2);
|
||||||
|
detail->aug_3 = inst->GetAugmentItemID(3);
|
||||||
|
detail->aug_4 = inst->GetAugmentItemID(4);
|
||||||
|
detail->aug_5 = inst->GetAugmentItemID(5);
|
||||||
|
event_details.push_back(detail);
|
||||||
|
|
||||||
|
if (inst->IsClassBag()) {
|
||||||
|
for (uint8 sub_slot = EQEmu::invbag::SLOT_BEGIN; (sub_slot <= EQEmu::invbag::SLOT_END); ++sub_slot) { // this is to catch ALL items
|
||||||
|
const EQEmu::ItemInstance* bag_inst = inst->GetItem(sub_slot);
|
||||||
|
if (bag_inst) {
|
||||||
|
detail = new QSDropItems_Struct;
|
||||||
|
detail->item_id = bag_inst->GetID();
|
||||||
|
detail->charges = (!bag_inst->IsStackable() ? 1 : bag_inst->GetCharges());
|
||||||
|
detail->aug_1 = bag_inst->GetAugmentItemID(1);
|
||||||
|
detail->aug_2 = bag_inst->GetAugmentItemID(2);
|
||||||
|
detail->aug_3 = bag_inst->GetAugmentItemID(3);
|
||||||
|
detail->aug_4 = bag_inst->GetAugmentItemID(4);
|
||||||
|
detail->aug_5 = bag_inst->GetAugmentItemID(5);
|
||||||
|
event_details.push_back(detail);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
qs_audit._detail_count = event_details.size();
|
||||||
|
|
||||||
|
auto qs_pack = new ServerPacket(
|
||||||
|
ServerOP_QSPlayerDropItem,
|
||||||
|
sizeof(QSPlayerDropItem_Struct) +
|
||||||
|
(sizeof(QSDropItems_Struct) * qs_audit._detail_count));
|
||||||
|
QSPlayerDropItem_Struct* qs_buf = (QSPlayerDropItem_Struct*) qs_pack->pBuffer;
|
||||||
|
|
||||||
|
memcpy(qs_buf, &qs_audit, sizeof(QSPlayerDropItem_Struct));
|
||||||
|
|
||||||
|
int offset = 0;
|
||||||
|
|
||||||
|
for (auto iter = event_details.begin(); iter != event_details.end(); ++iter, ++offset) {
|
||||||
|
QSDropItems_Struct* detail = reinterpret_cast<QSDropItems_Struct*>(*iter);
|
||||||
|
qs_buf->items[offset] = *detail;
|
||||||
|
safe_delete(detail);
|
||||||
|
}
|
||||||
|
|
||||||
|
event_details.clear();
|
||||||
|
|
||||||
|
if (worldserver.Connected())
|
||||||
|
worldserver.SendPacket(qs_pack);
|
||||||
|
|
||||||
|
safe_delete(qs_pack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Drop inst
|
// Drop inst
|
||||||
void Client::DropInst(const EQEmu::ItemInstance* inst)
|
void Client::DropInst(const EQEmu::ItemInstance* inst)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -988,7 +988,7 @@ public:
|
|||||||
void SendToFixZ(float new_x, float new_y, float new_z);
|
void SendToFixZ(float new_x, float new_y, float new_z);
|
||||||
float GetZOffset() const;
|
float GetZOffset() const;
|
||||||
float GetDefaultRaceSize() const;
|
float GetDefaultRaceSize() const;
|
||||||
void FixZ(int32 z_find_offset = 5);
|
void FixZ(int32 z_find_offset = 5, bool fix_client_z = false);
|
||||||
float GetFixedZ(glm::vec3 destination, int32 z_find_offset = 5);
|
float GetFixedZ(glm::vec3 destination, int32 z_find_offset = 5);
|
||||||
|
|
||||||
void NPCSpecialAttacks(const char* parse, int permtag, bool reset = true, bool remove = false);
|
void NPCSpecialAttacks(const char* parse, int permtag, bool reset = true, bool remove = false);
|
||||||
|
|||||||
@ -466,6 +466,7 @@ void NPC::AI_Init()
|
|||||||
roambox_distance = 0;
|
roambox_distance = 0;
|
||||||
roambox_destination_x = 0;
|
roambox_destination_x = 0;
|
||||||
roambox_destination_y = 0;
|
roambox_destination_y = 0;
|
||||||
|
roambox_destination_z = 0;
|
||||||
roambox_min_delay = 2500;
|
roambox_min_delay = 2500;
|
||||||
roambox_delay = 2500;
|
roambox_delay = 2500;
|
||||||
}
|
}
|
||||||
@ -779,44 +780,50 @@ void Client::AI_Process()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(RuleB(Combat, EnableFearPathing)){
|
if (RuleB(Combat, EnableFearPathing)) {
|
||||||
if(currently_fleeing) {
|
if (currently_fleeing) {
|
||||||
|
|
||||||
if (fix_z_timer_engaged.Check())
|
if (fix_z_timer.Check())
|
||||||
this->FixZ();
|
this->FixZ(5, true);
|
||||||
|
|
||||||
if(IsRooted()) {
|
if (IsRooted()) {
|
||||||
//make sure everybody knows were not moving, for appearance sake
|
//make sure everybody knows were not moving, for appearance sake
|
||||||
if(IsMoving())
|
if (IsMoving()) {
|
||||||
{
|
if (GetTarget())
|
||||||
if(GetTarget())
|
|
||||||
SetHeading(CalculateHeadingToTarget(GetTarget()->GetX(), GetTarget()->GetY()));
|
SetHeading(CalculateHeadingToTarget(GetTarget()->GetX(), GetTarget()->GetY()));
|
||||||
SetCurrentSpeed(0);
|
SetCurrentSpeed(0);
|
||||||
}
|
}
|
||||||
//continue on to attack code, ensuring that we execute the engaged code
|
//continue on to attack code, ensuring that we execute the engaged code
|
||||||
engaged = true;
|
engaged = true;
|
||||||
} else {
|
}
|
||||||
if(AI_movement_timer->Check()) {
|
else {
|
||||||
|
if (AI_movement_timer->Check()) {
|
||||||
int speed = GetFearSpeed();
|
int speed = GetFearSpeed();
|
||||||
animation = speed;
|
animation = speed;
|
||||||
speed *= 2;
|
speed *= 2;
|
||||||
SetCurrentSpeed(speed);
|
SetCurrentSpeed(speed);
|
||||||
// Check if we have reached the last fear point
|
// Check if we have reached the last fear point
|
||||||
if ((std::abs(GetX() - m_FearWalkTarget.x) < 0.1) &&
|
if ((std::abs(GetX() - m_FearWalkTarget.x) < 0.1) &&
|
||||||
(std::abs(GetY() - m_FearWalkTarget.y) < 0.1)) {
|
(std::abs(GetY() - m_FearWalkTarget.y) < 0.1)) {
|
||||||
// Calculate a new point to run to
|
// Calculate a new point to run to
|
||||||
CalculateNewFearpoint();
|
CalculateNewFearpoint();
|
||||||
}
|
}
|
||||||
if(!RuleB(Pathing, Fear) || !zone->pathing)
|
|
||||||
|
if (!RuleB(Pathing, Fear) || !zone->pathing)
|
||||||
CalculateNewPosition(m_FearWalkTarget.x, m_FearWalkTarget.y, m_FearWalkTarget.z, speed, true);
|
CalculateNewPosition(m_FearWalkTarget.x, m_FearWalkTarget.y, m_FearWalkTarget.z, speed, true);
|
||||||
else
|
else {
|
||||||
{
|
bool waypoint_changed, node_reached;
|
||||||
bool WaypointChanged, NodeReached;
|
|
||||||
|
|
||||||
glm::vec3 Goal = UpdatePath(m_FearWalkTarget.x, m_FearWalkTarget.y, m_FearWalkTarget.z,
|
glm::vec3 Goal = UpdatePath(
|
||||||
speed, WaypointChanged, NodeReached);
|
m_FearWalkTarget.x,
|
||||||
|
m_FearWalkTarget.y,
|
||||||
|
m_FearWalkTarget.z,
|
||||||
|
speed,
|
||||||
|
waypoint_changed,
|
||||||
|
node_reached
|
||||||
|
);
|
||||||
|
|
||||||
if(WaypointChanged)
|
if (waypoint_changed)
|
||||||
tar_ndx = 20;
|
tar_ndx = 20;
|
||||||
|
|
||||||
CalculateNewPosition(Goal.x, Goal.y, Goal.z, speed);
|
CalculateNewPosition(Goal.x, Goal.y, Goal.z, speed);
|
||||||
@ -1136,8 +1143,12 @@ void Mob::AI_Process() {
|
|||||||
bool WaypointChanged, NodeReached;
|
bool WaypointChanged, NodeReached;
|
||||||
|
|
||||||
glm::vec3 Goal = UpdatePath(
|
glm::vec3 Goal = UpdatePath(
|
||||||
m_FearWalkTarget.x, m_FearWalkTarget.y, m_FearWalkTarget.z,
|
m_FearWalkTarget.x,
|
||||||
GetFearSpeed(), WaypointChanged, NodeReached
|
m_FearWalkTarget.y,
|
||||||
|
m_FearWalkTarget.z,
|
||||||
|
GetFearSpeed(),
|
||||||
|
WaypointChanged,
|
||||||
|
NodeReached
|
||||||
);
|
);
|
||||||
|
|
||||||
if (WaypointChanged)
|
if (WaypointChanged)
|
||||||
@ -1696,6 +1707,14 @@ void NPC::AI_DoMovement() {
|
|||||||
(m_Position.z - 15)
|
(m_Position.z - 15)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If someone brought us into water when we naturally wouldn't path there, return to spawn
|
||||||
|
*/
|
||||||
|
if (zone->watermap->InLiquid(position) && zone->watermap->InLiquid(m_Position)) {
|
||||||
|
roambox_destination_x = m_SpawnPoint.x;
|
||||||
|
roambox_destination_y = m_SpawnPoint.y;
|
||||||
|
}
|
||||||
|
|
||||||
if (zone->watermap->InLiquid(position)) {
|
if (zone->watermap->InLiquid(position)) {
|
||||||
Log(Logs::Detail,
|
Log(Logs::Detail,
|
||||||
Logs::NPCRoamBox, "%s | My destination is in water and I don't belong there!",
|
Logs::NPCRoamBox, "%s | My destination is in water and I don't belong there!",
|
||||||
@ -1706,6 +1725,12 @@ void NPC::AI_DoMovement() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glm::vec3 destination;
|
||||||
|
destination.x = roambox_destination_x;
|
||||||
|
destination.y = roambox_destination_y;
|
||||||
|
destination.z = m_Position.z;
|
||||||
|
roambox_destination_z = GetFixedZ(destination) + this->GetZOffset();
|
||||||
|
|
||||||
Log(Logs::Detail,
|
Log(Logs::Detail,
|
||||||
Logs::NPCRoamBox,
|
Logs::NPCRoamBox,
|
||||||
"Calculate | NPC: %s distance %.3f | min_x %.3f | max_x %.3f | final_x %.3f | min_y %.3f | max_y %.3f | final_y %.3f",
|
"Calculate | NPC: %s distance %.3f | min_x %.3f | max_x %.3f | final_x %.3f | min_y %.3f | max_y %.3f | final_y %.3f",
|
||||||
@ -1719,11 +1744,20 @@ void NPC::AI_DoMovement() {
|
|||||||
roambox_destination_y);
|
roambox_destination_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fix_z_timer.Check()) {
|
bool waypoint_changed, node_reached;
|
||||||
this->FixZ();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!CalculateNewPosition(roambox_destination_x, roambox_destination_y, m_Position.z, move_speed, true)) {
|
glm::vec3 Goal = UpdatePath(
|
||||||
|
roambox_destination_x,
|
||||||
|
roambox_destination_y,
|
||||||
|
roambox_destination_z,
|
||||||
|
move_speed,
|
||||||
|
waypoint_changed,
|
||||||
|
node_reached
|
||||||
|
);
|
||||||
|
|
||||||
|
CalculateNewPosition(Goal.x, Goal.y, Goal.z, move_speed, true);
|
||||||
|
|
||||||
|
if (m_Position.x == roambox_destination_x && m_Position.y == roambox_destination_y) {
|
||||||
time_until_can_move = Timer::GetCurrentTime() + RandomTimer(roambox_min_delay, roambox_delay);
|
time_until_can_move = Timer::GetCurrentTime() + RandomTimer(roambox_min_delay, roambox_delay);
|
||||||
SetMoving(false);
|
SetMoving(false);
|
||||||
this->FixZ();
|
this->FixZ();
|
||||||
|
|||||||
@ -540,6 +540,7 @@ protected:
|
|||||||
float roambox_distance;
|
float roambox_distance;
|
||||||
float roambox_destination_x;
|
float roambox_destination_x;
|
||||||
float roambox_destination_y;
|
float roambox_destination_y;
|
||||||
|
float roambox_destination_z;
|
||||||
uint32 roambox_delay;
|
uint32 roambox_delay;
|
||||||
uint32 roambox_min_delay;
|
uint32 roambox_min_delay;
|
||||||
|
|
||||||
|
|||||||
@ -528,6 +528,8 @@ bool Object::HandleClick(Client* sender, const ClickObject_Struct* click_object)
|
|||||||
if(cursordelete) // delete the item if it's a duplicate lore. We have to do this because the client expects the item packet
|
if(cursordelete) // delete the item if it's a duplicate lore. We have to do this because the client expects the item packet
|
||||||
sender->DeleteItemInInventory(EQEmu::invslot::slotCursor);
|
sender->DeleteItemInInventory(EQEmu::invslot::slotCursor);
|
||||||
|
|
||||||
|
sender->DropItemQS(m_inst, true);
|
||||||
|
|
||||||
if(!m_ground_spawn)
|
if(!m_ground_spawn)
|
||||||
safe_delete(m_inst);
|
safe_delete(m_inst);
|
||||||
|
|
||||||
|
|||||||
@ -793,26 +793,34 @@ float Mob::GetFixedZ(glm::vec3 destination, int32 z_find_offset) {
|
|||||||
return new_z;
|
return new_z;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mob::FixZ(int32 z_find_offset /*= 5*/) {
|
void Mob::FixZ(int32 z_find_offset /*= 5*/, bool fix_client_z /*= false*/) {
|
||||||
glm::vec3 current_loc(m_Position);
|
glm::vec3 current_loc(m_Position);
|
||||||
float new_z = GetFixedZ(current_loc, z_find_offset);
|
|
||||||
|
|
||||||
if (!IsClient() && new_z != m_Position.z) {
|
if (IsClient() && !fix_client_z)
|
||||||
if ((new_z > -2000) && new_z != BEST_Z_INVALID) {
|
return;
|
||||||
if (RuleB(Map, MobZVisualDebug)) {
|
|
||||||
this->SendAppearanceEffect(78, 0, 0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_Position.z = new_z;
|
float new_z = GetFixedZ(current_loc, z_find_offset);
|
||||||
|
|
||||||
|
if (new_z == m_Position.z)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ((new_z > -2000) && new_z != BEST_Z_INVALID) {
|
||||||
|
if (RuleB(Map, MobZVisualDebug)) {
|
||||||
|
this->SendAppearanceEffect(78, 0, 0, 0, 0);
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
if (RuleB(Map, MobZVisualDebug)) {
|
|
||||||
this->SendAppearanceEffect(103, 0, 0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
Log(Logs::General, Logs::FixZ, "%s is failing to find Z %f",
|
m_Position.z = new_z;
|
||||||
this->GetCleanName(), std::abs(m_Position.z - new_z));
|
}
|
||||||
|
else {
|
||||||
|
if (RuleB(Map, MobZVisualDebug)) {
|
||||||
|
this->SendAppearanceEffect(103, 0, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Log(Logs::General,
|
||||||
|
Logs::FixZ,
|
||||||
|
"%s is failing to find Z %f",
|
||||||
|
this->GetCleanName(),
|
||||||
|
std::abs(m_Position.z - new_z));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -904,10 +904,10 @@ bool Zone::Init(bool iStaticZone) {
|
|||||||
RuleManager::Instance()->LoadRules(&database, r_name.c_str());
|
RuleManager::Instance()->LoadRules(&database, r_name.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
zone->zonemap = Map::LoadMapFile(zone->map_name);
|
zone->zonemap = Map::LoadMapFile(zone->map_name);
|
||||||
zone->watermap = WaterMap::LoadWaterMapfile(zone->map_name);
|
zone->watermap = WaterMap::LoadWaterMapfile(zone->map_name);
|
||||||
zone->pathing = IPathfinder::Load(zone->map_name);
|
zone->pathing = IPathfinder::Load(zone->map_name);
|
||||||
|
|
||||||
Log(Logs::General, Logs::Status, "Loading spawn conditions...");
|
Log(Logs::General, Logs::Status, "Loading spawn conditions...");
|
||||||
if(!spawn_conditions.LoadSpawnConditions(short_name, instanceid)) {
|
if(!spawn_conditions.LoadSpawnConditions(short_name, instanceid)) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user