mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-11 21:01:29 +00:00
Merge branch 'master' of https://github.com/EQEmu/Server into shutdown_crash
Conflicts: changelog.txt
This commit is contained in:
commit
6a4f7466f0
@ -3,6 +3,51 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
|||||||
== 08/24/2014 ==
|
== 08/24/2014 ==
|
||||||
Uleat: Fix (attempted) for zone crashes related to zone shut-down. This change disables all Mob AI and disables/deletes all Mob timers once Zone::ShutDown() is called. More areas will be addressed as reports come in.
|
Uleat: Fix (attempted) for zone crashes related to zone shut-down. This change disables all Mob AI and disables/deletes all Mob timers once Zone::ShutDown() is called. More areas will be addressed as reports come in.
|
||||||
Note: Perl and Lua quests tested to work..please post any aberrant behavior. (I finally set my spell-check to US English...)
|
Note: Perl and Lua quests tested to work..please post any aberrant behavior. (I finally set my spell-check to US English...)
|
||||||
|
Akkadius: Character creation process crash fix and query cleanup
|
||||||
|
Akkadius: Created `character_lookup` table for applications that mirrors all `character_` table fields minus blob fields for application lookups
|
||||||
|
- A 2.4GB character_ table will take 7 seconds to query on a SSD versus .1s on the character_lookup table
|
||||||
|
- This also causes applications like Magelo to burst reads of the entire character table because of the blob fields that come with the reads, as much as 500-600MB/s even if a indexed id filter is provided
|
||||||
|
- This field is synchronized on player save and has 0.001s DB hit
|
||||||
|
- When we split out from the blob, ideally this table can be removed
|
||||||
|
- Required SQL: utils\sql\git\required\2014_08_24_character_lookup.sql
|
||||||
|
|
||||||
|
== 08/23/2014 ==
|
||||||
|
Akkadius: Changed zone process window title format, example: 'crushbone :: clients: 6 inst_id: 1 inst_ver: 0 :: port: 7015'
|
||||||
|
Akkadius: Most of the following changes are QueryServ related, fully implemented its original functionality to be able to offload
|
||||||
|
intensive or metric based logging to a remote server process that could exist on another server entirely
|
||||||
|
Akkadius: Implemented Player Event Logging Types (Go to table `qs_player_events`):
|
||||||
|
1 = Player_Log_Quest,
|
||||||
|
2 = Player_Log_Zoning,
|
||||||
|
3 = Player_Log_Deaths,
|
||||||
|
4 = Player_Log_Connect_State,
|
||||||
|
5 = Player_Log_Levels,
|
||||||
|
6 = Player_Log_Keyring_Addition,
|
||||||
|
7 = Player_Log_QGlobal_Update,
|
||||||
|
8 = Player_Log_Task_Updates,
|
||||||
|
9 = Player_Log_AA_Purchases,
|
||||||
|
10 = Player_Log_Trade_Skill_Events,
|
||||||
|
11 = Player_Log_Issued_Commands,
|
||||||
|
12 = Player_Log_Money_Transactions,
|
||||||
|
13 = Player_Log_Alternate_Currency_Transactions,
|
||||||
|
- All QueryServ logging will be implemented with a front end in EoC 2.0 very soon
|
||||||
|
- Architecture page: http://wiki.eqemulator.org/p?QueryServ_Architecture
|
||||||
|
Akkadius: Changed all QS Error related logging to 'QUERYSERV__ERROR'
|
||||||
|
Akkadius: (Natedog) (Crash Fix) Legacy MySQL bug revert for loading AA's COALESCE( from COALESCE (
|
||||||
|
Akkadius: Implemented Perl Quest objects (LUA still needed to be exported):
|
||||||
|
- quest::qs_send_query("MySQL query") - Will send a raw query to the QueryServ process, useful for custom logging
|
||||||
|
- quest::qs_player_event(char_id, event_desc); - Will process a quest type event to table `qs_player_events`
|
||||||
|
Akkadius: Added MySQL Tables
|
||||||
|
- `qs_player_aa_rate_hourly`
|
||||||
|
- `qs_player_events`
|
||||||
|
- Source table structures from:
|
||||||
|
- utils\sql\git\queryserv\required\08_23_2014_player_events_and_player_aa_rate_hourly
|
||||||
|
To get the complete QueryServ schema, source from here:
|
||||||
|
- utils\sql\git\queryserv\required\Complete_QueryServ_Table_Structures.sql
|
||||||
|
Akkadius: Added rules for each logging type, source rules here with them enabled by default:
|
||||||
|
- utils\sql\git\queryserv\required\Complete_QueryServ_Rules_Enabled.sql
|
||||||
|
Akkadius: Spawn related logging cleanup
|
||||||
|
Akkadius: General code cleanup
|
||||||
|
Akkadius: More to come for QueryServ
|
||||||
|
|
||||||
== 08/20/2014 ==
|
== 08/20/2014 ==
|
||||||
Uleat: Rework of Trade::AddEntity() - function used to move items into the trade window. Now accepts argument for 'stack_size' and updates client properly.
|
Uleat: Rework of Trade::AddEntity() - function used to move items into the trade window. Now accepts argument for 'stack_size' and updates client properly.
|
||||||
|
|||||||
@ -608,10 +608,11 @@ bool Database::StoreCharacter(uint32 account_id, PlayerProfile_Struct* pp, Inven
|
|||||||
for (int16 i=EmuConstants::EQUIPMENT_BEGIN; i<=EmuConstants::BANK_BAGS_END;)
|
for (int16 i=EmuConstants::EQUIPMENT_BEGIN; i<=EmuConstants::BANK_BAGS_END;)
|
||||||
{
|
{
|
||||||
const ItemInst* newinv = inv->GetItem(i);
|
const ItemInst* newinv = inv->GetItem(i);
|
||||||
if (!newinv)
|
if (newinv)
|
||||||
{
|
{
|
||||||
invquery = StringFormat("INSERT INTO inventory SET charid=%0u, slotid=%0d, itemid=%0u, charges=%0d, color=%0u",
|
invquery = StringFormat("INSERT INTO `inventory` (charid, slotid, itemid, charges, color) VALUES (%u, %i, %u, %i, %u)",
|
||||||
charid, i, newinv->GetItem()->ID,newinv->GetCharges(), newinv->GetColor());
|
charid, i, newinv->GetItem()->ID, newinv->GetCharges(), newinv->GetColor());
|
||||||
|
|
||||||
auto results = QueryDatabase(invquery);
|
auto results = QueryDatabase(invquery);
|
||||||
|
|
||||||
if (!results.RowsAffected())
|
if (!results.RowsAffected())
|
||||||
|
|||||||
@ -60,17 +60,17 @@ LOG_TYPE( UCS, PACKETS, DISABLED)
|
|||||||
|
|
||||||
LOG_CATEGORY( QUERYSERV )
|
LOG_CATEGORY( QUERYSERV )
|
||||||
LOG_TYPE( QUERYSERV, INIT, ENABLED )
|
LOG_TYPE( QUERYSERV, INIT, ENABLED )
|
||||||
LOG_TYPE( QUERYSERV, ERROR, ENABLED )
|
LOG_TYPE( QUERYSERV, ERROR, ENABLED )
|
||||||
LOG_TYPE( QUERYSERV, CLIENT, DISABLED )
|
LOG_TYPE( QUERYSERV, CLIENT, DISABLED )
|
||||||
LOG_TYPE( QUERYSERV, TRACE, DISABLED )
|
LOG_TYPE( QUERYSERV, TRACE, DISABLED )
|
||||||
LOG_TYPE( QUERYSERV, PACKETS, DISABLED)
|
LOG_TYPE( QUERYSERV, PACKETS, DISABLED)
|
||||||
|
|
||||||
LOG_CATEGORY(SOCKET_SERVER)
|
LOG_CATEGORY( SOCKET_SERVER)
|
||||||
LOG_TYPE(SOCKET_SERVER, INIT, ENABLED)
|
LOG_TYPE( SOCKET_SERVER, INIT, ENABLED)
|
||||||
LOG_TYPE(SOCKET_SERVER, ERROR, ENABLED)
|
LOG_TYPE( SOCKET_SERVER, ERROR, ENABLED)
|
||||||
LOG_TYPE(SOCKET_SERVER, CLIENT, DISABLED)
|
LOG_TYPE( SOCKET_SERVER, CLIENT, DISABLED)
|
||||||
LOG_TYPE(SOCKET_SERVER, TRACE, DISABLED)
|
LOG_TYPE( SOCKET_SERVER, TRACE, DISABLED)
|
||||||
LOG_TYPE(SOCKET_SERVER, PACKETS, DISABLED)
|
LOG_TYPE( SOCKET_SERVER, PACKETS, DISABLED)
|
||||||
|
|
||||||
LOG_CATEGORY( SPAWNS )
|
LOG_CATEGORY( SPAWNS )
|
||||||
LOG_TYPE( SPAWNS, MAIN, DISABLED )
|
LOG_TYPE( SPAWNS, MAIN, DISABLED )
|
||||||
@ -108,6 +108,7 @@ LOG_CATEGORY( FACTION )
|
|||||||
|
|
||||||
LOG_CATEGORY( ZONE )
|
LOG_CATEGORY( ZONE )
|
||||||
LOG_TYPE( ZONE, GROUND_SPAWNS, DISABLED )
|
LOG_TYPE( ZONE, GROUND_SPAWNS, DISABLED )
|
||||||
|
LOG_TYPE( ZONE, SPAWNS, ENABLED)
|
||||||
LOG_TYPE( ZONE, INIT, ENABLED )
|
LOG_TYPE( ZONE, INIT, ENABLED )
|
||||||
LOG_TYPE( ZONE, INIT_ERR, ENABLED )
|
LOG_TYPE( ZONE, INIT_ERR, ENABLED )
|
||||||
LOG_TYPE( ZONE, WORLD, ENABLED )
|
LOG_TYPE( ZONE, WORLD, ENABLED )
|
||||||
@ -116,7 +117,7 @@ LOG_TYPE( ZONE, WORLD_TRACE, DISABLED )
|
|||||||
|
|
||||||
LOG_CATEGORY( TASKS )
|
LOG_CATEGORY( TASKS )
|
||||||
LOG_TYPE( TASKS, GLOBALLOAD, DISABLED )
|
LOG_TYPE( TASKS, GLOBALLOAD, DISABLED )
|
||||||
LOG_TYPE( TASKS, CLIENTLOAD, DISABLED )
|
LOG_TYPE( TASKS, CLIENTLOAD, DISABLED )
|
||||||
LOG_TYPE( TASKS, UPDATE, DISABLED )
|
LOG_TYPE( TASKS, UPDATE, DISABLED )
|
||||||
LOG_TYPE( TASKS, CLIENTSAVE, DISABLED )
|
LOG_TYPE( TASKS, CLIENTSAVE, DISABLED )
|
||||||
LOG_TYPE( TASKS, PACKETS, DISABLED )
|
LOG_TYPE( TASKS, PACKETS, DISABLED )
|
||||||
|
|||||||
@ -558,14 +558,28 @@ RULE_INT ( Console, SessionTimeOut, 600000 ) // Amount of time in ms for the con
|
|||||||
RULE_CATEGORY_END()
|
RULE_CATEGORY_END()
|
||||||
|
|
||||||
RULE_CATEGORY( QueryServ )
|
RULE_CATEGORY( QueryServ )
|
||||||
RULE_BOOL( QueryServ, PlayerChatLogging, 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, 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
|
||||||
RULE_BOOL( QueryServ, PlayerLogMoves, false) // Logs Player Moves
|
RULE_BOOL( QueryServ, PlayerLogMoves, false) // Logs Player Moves
|
||||||
RULE_BOOL( QueryServ, MerchantLogTransactions, false) // Logs Merchant Transactions
|
RULE_BOOL( QueryServ, PlayerLogMerchantTransactions, false) // Logs Merchant Transactions
|
||||||
RULE_BOOL( QueryServ, PlayerLogPCCoordinates, false) // Logs Player Coordinates with certain events
|
RULE_BOOL( QueryServ, PlayerLogPCCoordinates, false) // Logs Player Coordinates with certain events
|
||||||
|
RULE_BOOL( QueryServ, PlayerLogDropItem, false) // Logs Player Drop Item
|
||||||
|
RULE_BOOL( QueryServ, PlayerLogZone, false) // Logs Player Zone Events
|
||||||
|
RULE_BOOL( QueryServ, PlayerLogDeaths, false) // Logs Player Deaths
|
||||||
|
RULE_BOOL( QueryServ, PlayerLogConnectDisconnect, false) // Logs Player Connect Disconnect State
|
||||||
|
RULE_BOOL( QueryServ, PlayerLogLevels, false) // Logs Player Leveling/Deleveling
|
||||||
|
RULE_BOOL( QueryServ, PlayerLogAARate, false) // Logs Player AA Experience Rates
|
||||||
|
RULE_BOOL( QueryServ, PlayerLogQGlobalUpdate, false) // Logs Player QGlobal Updates
|
||||||
|
RULE_BOOL( QueryServ, PlayerLogTaskUpdates, false) // Logs Player Task Updates
|
||||||
|
RULE_BOOL( QueryServ, PlayerLogKeyringAddition, false) // Log PLayer Keyring additions
|
||||||
|
RULE_BOOL( QueryServ, PlayerLogAAPurchases, false) // Log Player AA Purchases
|
||||||
|
RULE_BOOL( QueryServ, PlayerLogTradeSkillEvents, false) // Log Player Tradeskill Transactions
|
||||||
|
RULE_BOOL( QueryServ, PlayerLogIssuedCommandes, false ) // Log Player Issued Commands
|
||||||
|
RULE_BOOL( QueryServ, PlayerLogMoneyTransactions, false) // Log Player Money Transaction/Splits
|
||||||
|
RULE_BOOL( QueryServ, PlayerLogAlternateCurrencyTransactions, false) // Log Ploayer Alternate Currency Transactions
|
||||||
RULE_CATEGORY_END()
|
RULE_CATEGORY_END()
|
||||||
|
|
||||||
RULE_CATEGORY( Inventory )
|
RULE_CATEGORY( Inventory )
|
||||||
|
|||||||
@ -184,9 +184,11 @@
|
|||||||
#define ServerOP_QSPlayerLogNPCKills 0x4012
|
#define ServerOP_QSPlayerLogNPCKills 0x4012
|
||||||
#define ServerOP_QSPlayerLogDeletes 0x4013
|
#define ServerOP_QSPlayerLogDeletes 0x4013
|
||||||
#define ServerOP_QSPlayerLogMoves 0x4014
|
#define ServerOP_QSPlayerLogMoves 0x4014
|
||||||
#define ServerOP_QSMerchantLogTransactions 0x4015
|
#define ServerOP_QSPlayerLogMerchantTransactions 0x4015
|
||||||
|
#define ServerOP_QSSendQuery 0x4016
|
||||||
|
|
||||||
enum { QSG_LFGuild = 0 };
|
/* Query Serv Generic Packet Flag/Type Enumeration */
|
||||||
|
enum { QSG_LFGuild = 0 };
|
||||||
enum { QSG_LFGuild_PlayerMatches = 0, QSG_LFGuild_UpdatePlayerInfo, QSG_LFGuild_RequestPlayerInfo, QSG_LFGuild_UpdateGuildInfo, QSG_LFGuild_GuildMatches,
|
enum { QSG_LFGuild_PlayerMatches = 0, QSG_LFGuild_UpdatePlayerInfo, QSG_LFGuild_RequestPlayerInfo, QSG_LFGuild_UpdateGuildInfo, QSG_LFGuild_GuildMatches,
|
||||||
QSG_LFGuild_RequestGuildInfo };
|
QSG_LFGuild_RequestGuildInfo };
|
||||||
|
|
||||||
@ -1219,6 +1221,10 @@ struct QSMerchantLogTransaction_Struct {
|
|||||||
QSTransactionItems_Struct items[0];
|
QSTransactionItems_Struct items[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct QSGeneralQuery_Struct {
|
||||||
|
char QueryString[0];
|
||||||
|
};
|
||||||
|
|
||||||
struct CZMessagePlayer_Struct {
|
struct CZMessagePlayer_Struct {
|
||||||
uint32 Type;
|
uint32 Type;
|
||||||
char CharName[64];
|
char CharName[64];
|
||||||
|
|||||||
@ -23,12 +23,13 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errmsg.h>
|
#include <errmsg.h>
|
||||||
#include <mysqld_error.h>
|
#include <mysqld_error.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
// Disgrace: for windows compile
|
// Disgrace: for windows compile
|
||||||
#ifdef _WINDOWS
|
#ifdef _WINDOWS
|
||||||
@ -95,42 +96,7 @@ Close the connection to the database
|
|||||||
Database::~Database()
|
Database::~Database()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Database::GetVariable(const char* varname, char* varvalue, uint16 varvalue_len) {
|
|
||||||
|
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
|
||||||
char* query = 0;
|
|
||||||
MYSQL_RES *result;
|
|
||||||
MYSQL_ROW row;
|
|
||||||
|
|
||||||
if (!RunQuery(query,MakeAnyLenString(&query, "select `value` from `variables` where `varname`='%s'", varname), errbuf, &result)) {
|
|
||||||
|
|
||||||
_log(UCS__ERROR, "Unable to get message count from database. %s %s", query, errbuf);
|
|
||||||
|
|
||||||
safe_delete_array(query);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
safe_delete_array(query);
|
|
||||||
|
|
||||||
if (mysql_num_rows(result) != 1) {
|
|
||||||
|
|
||||||
mysql_free_result(result);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
row = mysql_fetch_row(result);
|
|
||||||
|
|
||||||
snprintf(varvalue, varvalue_len, "%s", row[0]);
|
|
||||||
|
|
||||||
mysql_free_result(result);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Database::AddSpeech(const char* from, const char* to, const char* message, uint16 minstatus, uint32 guilddbid, uint8 type) {
|
void Database::AddSpeech(const char* from, const char* to, const char* message, uint16 minstatus, uint32 guilddbid, uint8 type) {
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||||
char* query = 0;
|
char* query = 0;
|
||||||
@ -143,8 +109,8 @@ void Database::AddSpeech(const char* from, const char* to, const char* message,
|
|||||||
DoEscapeString(S3, message, strlen(message));
|
DoEscapeString(S3, message, strlen(message));
|
||||||
|
|
||||||
if(!RunQuery(query, MakeAnyLenString(&query, "INSERT INTO `qs_player_speech` SET `from`='%s', `to`='%s', `message`='%s', `minstatus`='%i', `guilddbid`='%i', `type`='%i'", S1, S2, S3, minstatus, guilddbid, type), errbuf, 0, 0)) {
|
if(!RunQuery(query, MakeAnyLenString(&query, "INSERT INTO `qs_player_speech` SET `from`='%s', `to`='%s', `message`='%s', `minstatus`='%i', `guilddbid`='%i', `type`='%i'", S1, S2, S3, minstatus, guilddbid, type), errbuf, 0, 0)) {
|
||||||
_log(NET__WORLD, "Failed Speech Entry Insert: %s", errbuf);
|
_log(QUERYSERV__ERROR, "Failed Speech Entry Insert: %s", errbuf);
|
||||||
_log(NET__WORLD, "%s", query);
|
_log(QUERYSERV__ERROR, "%s", query);
|
||||||
}
|
}
|
||||||
|
|
||||||
safe_delete_array(query);
|
safe_delete_array(query);
|
||||||
@ -164,8 +130,8 @@ void Database::LogPlayerTrade(QSPlayerLogTrade_Struct* QS, uint32 Items) {
|
|||||||
QS->char1_id, QS->char1_money.platinum, QS->char1_money.gold, QS->char1_money.silver, QS->char1_money.copper, QS->char1_count,
|
QS->char1_id, QS->char1_money.platinum, QS->char1_money.gold, QS->char1_money.silver, QS->char1_money.copper, QS->char1_count,
|
||||||
QS->char2_id, QS->char2_money.platinum, QS->char2_money.gold, QS->char2_money.silver, QS->char2_money.copper, QS->char2_count),
|
QS->char2_id, QS->char2_money.platinum, QS->char2_money.gold, QS->char2_money.silver, QS->char2_money.copper, QS->char2_count),
|
||||||
errbuf, 0, 0, &lastid)) {
|
errbuf, 0, 0, &lastid)) {
|
||||||
_log(NET__WORLD, "Failed Trade Log Record Insert: %s", errbuf);
|
_log(QUERYSERV__ERROR, "Failed Trade Log Record Insert: %s", errbuf);
|
||||||
_log(NET__WORLD, "%s", query);
|
_log(QUERYSERV__ERROR, "%s", query);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Items > 0) {
|
if(Items > 0) {
|
||||||
@ -176,15 +142,14 @@ void Database::LogPlayerTrade(QSPlayerLogTrade_Struct* QS, uint32 Items) {
|
|||||||
lastid, QS->items[i].from_id, QS->items[i].from_slot, QS->items[i].to_id, QS->items[i].to_slot, QS->items[i].item_id,
|
lastid, QS->items[i].from_id, QS->items[i].from_slot, QS->items[i].to_id, QS->items[i].to_slot, 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,
|
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,
|
||||||
errbuf, 0, 0))) {
|
errbuf, 0, 0))) {
|
||||||
_log(NET__WORLD, "Failed Trade Log Record Entry Insert: %s", errbuf);
|
_log(QUERYSERV__ERROR, "Failed Trade Log Record Entry Insert: %s", errbuf);
|
||||||
_log(NET__WORLD, "%s", query);
|
_log(QUERYSERV__ERROR, "%s", query);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::LogPlayerHandin(QSPlayerLogHandin_Struct* QS, uint32 Items) {
|
void Database::LogPlayerHandin(QSPlayerLogHandin_Struct* QS, uint32 Items) {
|
||||||
|
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||||
char* query = 0;
|
char* query = 0;
|
||||||
uint32 lastid = 0;
|
uint32 lastid = 0;
|
||||||
@ -194,8 +159,8 @@ void Database::LogPlayerHandin(QSPlayerLogHandin_Struct* QS, uint32 Items) {
|
|||||||
QS->quest_id, QS->char_id, QS->char_money.platinum, QS->char_money.gold, QS->char_money.silver, QS->char_money.copper, QS->char_count,
|
QS->quest_id, QS->char_id, QS->char_money.platinum, QS->char_money.gold, QS->char_money.silver, QS->char_money.copper, QS->char_count,
|
||||||
QS->npc_id, QS->npc_money.platinum, QS->npc_money.gold, QS->npc_money.silver, QS->npc_money.copper, QS->npc_count),
|
QS->npc_id, QS->npc_money.platinum, QS->npc_money.gold, QS->npc_money.silver, QS->npc_money.copper, QS->npc_count),
|
||||||
errbuf, 0, 0, &lastid)) {
|
errbuf, 0, 0, &lastid)) {
|
||||||
_log(NET__WORLD, "Failed Handin Log Record Insert: %s", errbuf);
|
_log(QUERYSERV__ERROR, "Failed Handin Log Record Insert: %s", errbuf);
|
||||||
_log(NET__WORLD, "%s", query);
|
_log(QUERYSERV__ERROR, "%s", query);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Items > 0) {
|
if(Items > 0) {
|
||||||
@ -206,8 +171,8 @@ void Database::LogPlayerHandin(QSPlayerLogHandin_Struct* QS, uint32 Items) {
|
|||||||
lastid, QS->items[i].action_type, QS->items[i].char_slot, QS->items[i].item_id, QS->items[i].charges,
|
lastid, QS->items[i].action_type, QS->items[i].char_slot, 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,
|
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,
|
||||||
errbuf, 0, 0))) {
|
errbuf, 0, 0))) {
|
||||||
_log(NET__WORLD, "Failed Handin Log Record Entry Insert: %s", errbuf);
|
_log(QUERYSERV__ERROR, "Failed Handin Log Record Entry Insert: %s", errbuf);
|
||||||
_log(NET__WORLD, "%s", query);
|
_log(QUERYSERV__ERROR, "%s", query);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -218,15 +183,15 @@ void Database::LogPlayerNPCKill(QSPlayerLogNPCKill_Struct* QS, uint32 Members){
|
|||||||
char* query = 0;
|
char* query = 0;
|
||||||
uint32 lastid = 0;
|
uint32 lastid = 0;
|
||||||
if(!RunQuery(query, MakeAnyLenString(&query, "INSERT INTO `qs_player_npc_kill_record` SET `npc_id`='%i', `type`='%i', `zone_id`='%i', `time`=NOW()", QS->s1.NPCID, QS->s1.Type, QS->s1.ZoneID), errbuf, 0, 0, &lastid)) {
|
if(!RunQuery(query, MakeAnyLenString(&query, "INSERT INTO `qs_player_npc_kill_record` SET `npc_id`='%i', `type`='%i', `zone_id`='%i', `time`=NOW()", QS->s1.NPCID, QS->s1.Type, QS->s1.ZoneID), errbuf, 0, 0, &lastid)) {
|
||||||
_log(NET__WORLD, "Failed NPC Kill Log Record Insert: %s", errbuf);
|
_log(QUERYSERV__ERROR, "Failed NPC Kill Log Record Insert: %s", errbuf);
|
||||||
_log(NET__WORLD, "%s", query);
|
_log(QUERYSERV__ERROR, "%s", query);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Members > 0){
|
if(Members > 0){
|
||||||
for (int i = 0; i < Members; i++) {
|
for (int i = 0; i < Members; i++) {
|
||||||
if(!RunQuery(query, MakeAnyLenString(&query, "INSERT INTO `qs_player_npc_kill_record_entries` SET `event_id`='%i', `char_id`='%i'", lastid, QS->Chars[i].char_id, errbuf, 0, 0))) {
|
if(!RunQuery(query, MakeAnyLenString(&query, "INSERT INTO `qs_player_npc_kill_record_entries` SET `event_id`='%i', `char_id`='%i'", lastid, QS->Chars[i].char_id, errbuf, 0, 0))) {
|
||||||
_log(NET__WORLD, "Failed NPC Kill Log Entry Insert: %s", errbuf);
|
_log(QUERYSERV__ERROR, "Failed NPC Kill Log Entry Insert: %s", errbuf);
|
||||||
_log(NET__WORLD, "%s", query);
|
_log(QUERYSERV__ERROR, "%s", query);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -241,8 +206,8 @@ void Database::LogPlayerDelete(QSPlayerLogDelete_Struct* QS, uint32 Items) {
|
|||||||
"`char_id`='%i', `stack_size`='%i', `char_items`='%i'",
|
"`char_id`='%i', `stack_size`='%i', `char_items`='%i'",
|
||||||
QS->char_id, QS->stack_size, QS->char_count, QS->char_count),
|
QS->char_id, QS->stack_size, QS->char_count, QS->char_count),
|
||||||
errbuf, 0, 0, &lastid)) {
|
errbuf, 0, 0, &lastid)) {
|
||||||
_log(NET__WORLD, "Failed Delete Log Record Insert: %s", errbuf);
|
_log(QUERYSERV__ERROR, "Failed Delete Log Record Insert: %s", errbuf);
|
||||||
_log(NET__WORLD, "%s", query);
|
_log(QUERYSERV__ERROR, "%s", query);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Items > 0) {
|
if(Items > 0) {
|
||||||
@ -253,15 +218,15 @@ void Database::LogPlayerDelete(QSPlayerLogDelete_Struct* QS, uint32 Items) {
|
|||||||
lastid, QS->items[i].char_slot, QS->items[i].item_id, QS->items[i].charges, QS->items[i].aug_1,
|
lastid, QS->items[i].char_slot, 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,
|
QS->items[i].aug_2, QS->items[i].aug_3, QS->items[i].aug_4, QS->items[i].aug_5,
|
||||||
errbuf, 0, 0))) {
|
errbuf, 0, 0))) {
|
||||||
_log(NET__WORLD, "Failed Delete Log Record Entry Insert: %s", errbuf);
|
_log(QUERYSERV__ERROR, "Failed Delete Log Record Entry Insert: %s", errbuf);
|
||||||
_log(NET__WORLD, "%s", query);
|
_log(QUERYSERV__ERROR, "%s", query);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::LogPlayerMove(QSPlayerLogMove_Struct* QS, uint32 Items) {
|
void Database::LogPlayerMove(QSPlayerLogMove_Struct* QS, uint32 Items) {
|
||||||
|
/* These are item moves */
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||||
char* query = 0;
|
char* query = 0;
|
||||||
uint32 lastid = 0;
|
uint32 lastid = 0;
|
||||||
@ -269,10 +234,9 @@ void Database::LogPlayerMove(QSPlayerLogMove_Struct* QS, uint32 Items) {
|
|||||||
"`char_id`='%i', `from_slot`='%i', `to_slot`='%i', `stack_size`='%i', `char_items`='%i', `postaction`='%i'",
|
"`char_id`='%i', `from_slot`='%i', `to_slot`='%i', `stack_size`='%i', `char_items`='%i', `postaction`='%i'",
|
||||||
QS->char_id, QS->from_slot, QS->to_slot, QS->stack_size, QS->char_count, QS->postaction),
|
QS->char_id, QS->from_slot, QS->to_slot, QS->stack_size, QS->char_count, QS->postaction),
|
||||||
errbuf, 0, 0, &lastid)) {
|
errbuf, 0, 0, &lastid)) {
|
||||||
_log(NET__WORLD, "Failed Move Log Record Insert: %s", errbuf);
|
_log(QUERYSERV__ERROR, "Failed Move Log Record Insert: %s", errbuf);
|
||||||
_log(NET__WORLD, "%s", query);
|
_log(QUERYSERV__ERROR, "%s", query);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Items > 0) {
|
if(Items > 0) {
|
||||||
for(int i = 0; i < Items; i++) {
|
for(int i = 0; i < Items; i++) {
|
||||||
if(!RunQuery(query, MakeAnyLenString(&query, "INSERT INTO `qs_player_move_record_entries` SET `event_id`='%i', "
|
if(!RunQuery(query, MakeAnyLenString(&query, "INSERT INTO `qs_player_move_record_entries` SET `event_id`='%i', "
|
||||||
@ -281,16 +245,15 @@ void Database::LogPlayerMove(QSPlayerLogMove_Struct* QS, uint32 Items) {
|
|||||||
QS->items[i].from_slot, QS->items[i].to_slot, QS->items[i].item_id, QS->items[i].charges,
|
QS->items[i].from_slot, QS->items[i].to_slot, 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,
|
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,
|
||||||
errbuf, 0, 0))) {
|
errbuf, 0, 0))) {
|
||||||
_log(NET__WORLD, "Failed Move Log Record Entry Insert: %s", errbuf);
|
_log(QUERYSERV__ERROR, "Failed Move Log Record Entry Insert: %s", errbuf);
|
||||||
_log(NET__WORLD, "%s", query);
|
_log(QUERYSERV__ERROR, "%s", query);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::LogMerchantTransaction(QSMerchantLogTransaction_Struct* QS, uint32 Items) {
|
void Database::LogMerchantTransaction(QSMerchantLogTransaction_Struct* QS, uint32 Items) {
|
||||||
// Merchant transactions are from the perspective of the merchant, not the player -U
|
/* Merchant transactions are from the perspective of the merchant, not the player -U */
|
||||||
|
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||||
char* query = 0;
|
char* query = 0;
|
||||||
uint32 lastid = 0;
|
uint32 lastid = 0;
|
||||||
@ -300,8 +263,8 @@ void Database::LogMerchantTransaction(QSMerchantLogTransaction_Struct* QS, uint3
|
|||||||
QS->zone_id, QS->merchant_id, QS->merchant_money.platinum, QS->merchant_money.gold, QS->merchant_money.silver, QS->merchant_money.copper, QS->merchant_count,
|
QS->zone_id, QS->merchant_id, QS->merchant_money.platinum, QS->merchant_money.gold, QS->merchant_money.silver, QS->merchant_money.copper, QS->merchant_count,
|
||||||
QS->char_id, QS->char_money.platinum, QS->char_money.gold, QS->char_money.silver, QS->char_money.copper, QS->char_count),
|
QS->char_id, QS->char_money.platinum, QS->char_money.gold, QS->char_money.silver, QS->char_money.copper, QS->char_count),
|
||||||
errbuf, 0, 0, &lastid)) {
|
errbuf, 0, 0, &lastid)) {
|
||||||
_log(NET__WORLD, "Failed Transaction Log Record Insert: %s", errbuf);
|
_log(QUERYSERV__ERROR, "Failed Transaction Log Record Insert: %s", errbuf);
|
||||||
_log(NET__WORLD, "%s", query);
|
_log(QUERYSERV__ERROR, "%s", query);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Items > 0) {
|
if(Items > 0) {
|
||||||
@ -312,10 +275,29 @@ void Database::LogMerchantTransaction(QSMerchantLogTransaction_Struct* QS, uint3
|
|||||||
lastid, QS->items[i].char_slot, QS->items[i].item_id, QS->items[i].charges, QS->items[i].aug_1,
|
lastid, QS->items[i].char_slot, 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,
|
QS->items[i].aug_2, QS->items[i].aug_3, QS->items[i].aug_4, QS->items[i].aug_5,
|
||||||
errbuf, 0, 0))) {
|
errbuf, 0, 0))) {
|
||||||
_log(NET__WORLD, "Failed Transaction Log Record Entry Insert: %s", errbuf);
|
_log(QUERYSERV__ERROR, "Failed Transaction Log Record Entry Insert: %s", errbuf);
|
||||||
_log(NET__WORLD, "%s", query);
|
_log(QUERYSERV__ERROR, "%s", query);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
safe_delete_array(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Database::GeneralQueryReceive(ServerPacket *pack) {
|
||||||
|
/*
|
||||||
|
These are general queries passed from anywhere in zone instead of packing structures and breaking them down again and again
|
||||||
|
*/
|
||||||
|
char *Query = nullptr;
|
||||||
|
Query = new char[pack->ReadUInt32() + 1];
|
||||||
|
pack->ReadString(Query);
|
||||||
|
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||||
|
char* query = 0;
|
||||||
|
uint32 lastid = 0;
|
||||||
|
if (!RunQuery(query, MakeAnyLenString(&query, Query), errbuf, 0, 0, &lastid)) {
|
||||||
|
_log(QUERYSERV__ERROR, "Failed Delete Log Record Insert: %s", errbuf);
|
||||||
|
_log(QUERYSERV__ERROR, "%s", query);
|
||||||
|
}
|
||||||
|
safe_delete_array(query);
|
||||||
|
safe_delete(pack);
|
||||||
|
safe_delete(Query);
|
||||||
|
}
|
||||||
|
|||||||
@ -42,7 +42,6 @@ public:
|
|||||||
bool Connect(const char* host, const char* user, const char* passwd, const char* database,uint32 port);
|
bool Connect(const char* host, const char* user, const char* passwd, const char* database,uint32 port);
|
||||||
~Database();
|
~Database();
|
||||||
|
|
||||||
bool GetVariable(const char* varname, char* varvalue, uint16 varvalue_len);
|
|
||||||
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 Items);
|
void LogPlayerTrade(QSPlayerLogTrade_Struct* QS, uint32 Items);
|
||||||
void LogPlayerHandin(QSPlayerLogHandin_Struct* QS, uint32 Items);
|
void LogPlayerHandin(QSPlayerLogHandin_Struct* QS, uint32 Items);
|
||||||
@ -50,6 +49,7 @@ public:
|
|||||||
void LogPlayerDelete(QSPlayerLogDelete_Struct* QS, uint32 Items);
|
void LogPlayerDelete(QSPlayerLogDelete_Struct* QS, uint32 Items);
|
||||||
void LogPlayerMove(QSPlayerLogMove_Struct* QS, uint32 Items);
|
void LogPlayerMove(QSPlayerLogMove_Struct* QS, uint32 Items);
|
||||||
void LogMerchantTransaction(QSMerchantLogTransaction_Struct* QS, uint32 Items);
|
void LogMerchantTransaction(QSMerchantLogTransaction_Struct* QS, uint32 Items);
|
||||||
|
void GeneralQueryReceive(ServerPacket *pack);
|
||||||
protected:
|
protected:
|
||||||
void HandleMysqlError(uint32 errnum);
|
void HandleMysqlError(uint32 errnum);
|
||||||
private:
|
private:
|
||||||
|
|||||||
@ -22,7 +22,7 @@ PlayerLookingForGuild::PlayerLookingForGuild(char *Name, char *Comments, uint32
|
|||||||
|
|
||||||
GuildLookingForPlayers::GuildLookingForPlayers(char *Name, char *Comments, uint32 FromLevel, uint32 ToLevel, uint32 Classes, uint32 AACount, uint32 Timezone, uint32 TimePosted)
|
GuildLookingForPlayers::GuildLookingForPlayers(char *Name, char *Comments, uint32 FromLevel, uint32 ToLevel, uint32 Classes, uint32 AACount, uint32 Timezone, uint32 TimePosted)
|
||||||
{
|
{
|
||||||
this->Name = Name;
|
this->Name = Name;
|
||||||
this->Comments = Comments;
|
this->Comments = Comments;
|
||||||
this->FromLevel = FromLevel;
|
this->FromLevel = FromLevel;
|
||||||
this->ToLevel = ToLevel;
|
this->ToLevel = ToLevel;
|
||||||
|
|||||||
@ -33,56 +33,47 @@
|
|||||||
|
|
||||||
volatile bool RunLoops = true;
|
volatile bool RunLoops = true;
|
||||||
|
|
||||||
uint32 MailMessagesSent = 0;
|
|
||||||
uint32 ChatMessagesSent = 0;
|
|
||||||
|
|
||||||
TimeoutManager timeout_manager;
|
TimeoutManager timeout_manager;
|
||||||
|
|
||||||
Database database;
|
Database database;
|
||||||
LFGuildManager lfguildmanager;
|
LFGuildManager lfguildmanager;
|
||||||
std::string WorldShortName;
|
std::string WorldShortName;
|
||||||
|
|
||||||
const queryservconfig *Config;
|
const queryservconfig *Config;
|
||||||
|
|
||||||
WorldServer *worldserver = 0;
|
WorldServer *worldserver = 0;
|
||||||
|
|
||||||
|
void CatchSignal(int sig_num) {
|
||||||
void CatchSignal(int sig_num) {
|
RunLoops = false;
|
||||||
|
|
||||||
RunLoops = false;
|
|
||||||
|
|
||||||
if(worldserver)
|
if(worldserver)
|
||||||
worldserver->Disconnect();
|
worldserver->Disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
RegisterExecutablePlatform(ExePlatformQueryServ);
|
RegisterExecutablePlatform(ExePlatformQueryServ);
|
||||||
set_exception_handler();
|
set_exception_handler();
|
||||||
|
Timer LFGuildExpireTimer(60000);
|
||||||
Timer LFGuildExpireTimer(60000);
|
|
||||||
|
|
||||||
Timer InterserverTimer(INTERSERVER_TIMER); // does auto-reconnect
|
Timer InterserverTimer(INTERSERVER_TIMER); // does auto-reconnect
|
||||||
|
|
||||||
|
/* Load XML from eqemu_config.xml
|
||||||
|
<qsdatabase>
|
||||||
|
<host>127.0.0.1</host>
|
||||||
|
<port>3306</port>
|
||||||
|
<username>user</username>
|
||||||
|
<password>password</password>
|
||||||
|
<db>dbname</db>
|
||||||
|
</qsdatabase>
|
||||||
|
*/
|
||||||
|
|
||||||
_log(QUERYSERV__INIT, "Starting EQEmu QueryServ.");
|
_log(QUERYSERV__INIT, "Starting EQEmu QueryServ.");
|
||||||
|
|
||||||
if (!queryservconfig::LoadConfig()) {
|
if (!queryservconfig::LoadConfig()) {
|
||||||
|
|
||||||
_log(QUERYSERV__INIT, "Loading server configuration failed.");
|
_log(QUERYSERV__INIT, "Loading server configuration failed.");
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Config = queryservconfig::get();
|
Config = queryservconfig::get();
|
||||||
|
WorldShortName = Config->ShortName;
|
||||||
if(!load_log_settings(Config->LogSettingsFile.c_str()))
|
|
||||||
_log(QUERYSERV__INIT, "Warning: Unable to read %s", Config->LogSettingsFile.c_str());
|
|
||||||
else
|
|
||||||
_log(QUERYSERV__INIT, "Log settings loaded from %s", Config->LogSettingsFile.c_str());
|
|
||||||
|
|
||||||
WorldShortName = Config->ShortName;
|
|
||||||
|
|
||||||
_log(QUERYSERV__INIT, "Connecting to MySQL...");
|
_log(QUERYSERV__INIT, "Connecting to MySQL...");
|
||||||
|
|
||||||
|
/* MySQL Connection */
|
||||||
if (!database.Connect(
|
if (!database.Connect(
|
||||||
Config->QSDatabaseHost.c_str(),
|
Config->QSDatabaseHost.c_str(),
|
||||||
Config->QSDatabaseUsername.c_str(),
|
Config->QSDatabaseUsername.c_str(),
|
||||||
@ -93,6 +84,12 @@ int main() {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Initialize Logging */
|
||||||
|
if (!load_log_settings(Config->LogSettingsFile.c_str()))
|
||||||
|
_log(QUERYSERV__INIT, "Warning: Unable to read %s", Config->LogSettingsFile.c_str());
|
||||||
|
else
|
||||||
|
_log(QUERYSERV__INIT, "Log settings loaded from %s", Config->LogSettingsFile.c_str());
|
||||||
|
|
||||||
if (signal(SIGINT, CatchSignal) == SIG_ERR) {
|
if (signal(SIGINT, CatchSignal) == SIG_ERR) {
|
||||||
_log(QUERYSERV__ERROR, "Could not set signal handler");
|
_log(QUERYSERV__ERROR, "Could not set signal handler");
|
||||||
return 1;
|
return 1;
|
||||||
@ -102,16 +99,15 @@ int main() {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Initial Connection to Worldserver */
|
||||||
worldserver = new WorldServer;
|
worldserver = new WorldServer;
|
||||||
|
worldserver->Connect();
|
||||||
|
|
||||||
worldserver->Connect();
|
/* Load Looking For Guild Manager */
|
||||||
|
|
||||||
lfguildmanager.LoadDatabase();
|
lfguildmanager.LoadDatabase();
|
||||||
|
|
||||||
while(RunLoops) {
|
while(RunLoops) {
|
||||||
|
Timer::SetCurrentTime();
|
||||||
Timer::SetCurrentTime();
|
|
||||||
|
|
||||||
if(LFGuildExpireTimer.Check())
|
if(LFGuildExpireTimer.Check())
|
||||||
lfguildmanager.ExpireEntries();
|
lfguildmanager.ExpireEntries();
|
||||||
|
|
||||||
@ -119,10 +115,8 @@ int main() {
|
|||||||
if (worldserver->TryReconnect() && (!worldserver->Connected()))
|
if (worldserver->TryReconnect() && (!worldserver->Connected()))
|
||||||
worldserver->AsyncConnect();
|
worldserver->AsyncConnect();
|
||||||
}
|
}
|
||||||
worldserver->Process();
|
worldserver->Process();
|
||||||
|
timeout_manager.CheckTimeouts();
|
||||||
timeout_manager.CheckTimeouts();
|
|
||||||
|
|
||||||
Sleep(100);
|
Sleep(100);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -56,122 +56,109 @@ void WorldServer::OnConnected()
|
|||||||
|
|
||||||
void WorldServer::Process()
|
void WorldServer::Process()
|
||||||
{
|
{
|
||||||
WorldConnection::Process();
|
WorldConnection::Process();
|
||||||
|
|
||||||
if (!Connected())
|
if (!Connected())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ServerPacket *pack = 0;
|
ServerPacket *pack = 0;
|
||||||
|
|
||||||
while((pack = tcpc.PopPacket()))
|
while((pack = tcpc.PopPacket()))
|
||||||
{
|
{
|
||||||
_log(QUERYSERV__TRACE, "Received Opcode: %4X", pack->opcode);
|
_log(QUERYSERV__TRACE, "Received Opcode: %4X", pack->opcode);
|
||||||
|
switch(pack->opcode) {
|
||||||
switch(pack->opcode)
|
|
||||||
{
|
|
||||||
case 0: {
|
case 0: {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ServerOP_KeepAlive:
|
case ServerOP_KeepAlive: {
|
||||||
{
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ServerOP_Speech:
|
case ServerOP_Speech: {
|
||||||
{
|
Server_Speech_Struct *SSS = (Server_Speech_Struct*)pack->pBuffer;
|
||||||
Server_Speech_Struct *SSS = (Server_Speech_Struct*)pack->pBuffer;
|
|
||||||
|
|
||||||
std::string tmp1 = SSS->from;
|
std::string tmp1 = SSS->from;
|
||||||
std::string tmp2 = SSS->to;
|
std::string tmp2 = SSS->to;
|
||||||
|
|
||||||
database.AddSpeech(tmp1.c_str(), tmp2.c_str(), SSS->message, SSS->minstatus, SSS->guilddbid, SSS->type);
|
database.AddSpeech(tmp1.c_str(), tmp2.c_str(), SSS->message, SSS->minstatus, SSS->guilddbid, SSS->type);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ServerOP_QSPlayerLogTrades:
|
case ServerOP_QSPlayerLogTrades: {
|
||||||
{
|
|
||||||
QSPlayerLogTrade_Struct *QS = (QSPlayerLogTrade_Struct*)pack->pBuffer;
|
QSPlayerLogTrade_Struct *QS = (QSPlayerLogTrade_Struct*)pack->pBuffer;
|
||||||
uint32 Items = QS->char1_count + QS->char2_count;
|
uint32 Items = QS->char1_count + QS->char2_count;
|
||||||
database.LogPlayerTrade(QS, Items);
|
database.LogPlayerTrade(QS, Items);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ServerOP_QSPlayerLogHandins:
|
case ServerOP_QSPlayerLogHandins: {
|
||||||
{
|
|
||||||
QSPlayerLogHandin_Struct *QS = (QSPlayerLogHandin_Struct*)pack->pBuffer;
|
QSPlayerLogHandin_Struct *QS = (QSPlayerLogHandin_Struct*)pack->pBuffer;
|
||||||
uint32 Items = QS->char_count + QS->npc_count;
|
uint32 Items = QS->char_count + QS->npc_count;
|
||||||
database.LogPlayerHandin(QS, Items);
|
database.LogPlayerHandin(QS, Items);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ServerOP_QSPlayerLogNPCKills:
|
case ServerOP_QSPlayerLogNPCKills: {
|
||||||
{
|
|
||||||
QSPlayerLogNPCKill_Struct *QS = (QSPlayerLogNPCKill_Struct*)pack->pBuffer;
|
QSPlayerLogNPCKill_Struct *QS = (QSPlayerLogNPCKill_Struct*)pack->pBuffer;
|
||||||
uint32 Members = pack->size - sizeof(QSPlayerLogNPCKill_Struct);
|
uint32 Members = pack->size - sizeof(QSPlayerLogNPCKill_Struct);
|
||||||
if (Members > 0) Members = Members / sizeof(QSPlayerLogNPCKillsPlayers_Struct);
|
if (Members > 0) Members = Members / sizeof(QSPlayerLogNPCKillsPlayers_Struct);
|
||||||
database.LogPlayerNPCKill(QS, Members);
|
database.LogPlayerNPCKill(QS, Members);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ServerOP_QSPlayerLogDeletes:
|
case ServerOP_QSPlayerLogDeletes: {
|
||||||
{
|
|
||||||
QSPlayerLogDelete_Struct *QS = (QSPlayerLogDelete_Struct*)pack->pBuffer;
|
QSPlayerLogDelete_Struct *QS = (QSPlayerLogDelete_Struct*)pack->pBuffer;
|
||||||
uint32 Items = QS->char_count;
|
uint32 Items = QS->char_count;
|
||||||
database.LogPlayerDelete(QS, Items);
|
database.LogPlayerDelete(QS, Items);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ServerOP_QSPlayerLogMoves:
|
case ServerOP_QSPlayerLogMoves: {
|
||||||
{
|
|
||||||
QSPlayerLogMove_Struct *QS = (QSPlayerLogMove_Struct*)pack->pBuffer;
|
QSPlayerLogMove_Struct *QS = (QSPlayerLogMove_Struct*)pack->pBuffer;
|
||||||
uint32 Items = QS->char_count;
|
uint32 Items = QS->char_count;
|
||||||
database.LogPlayerMove(QS, Items);
|
database.LogPlayerMove(QS, Items);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ServerOP_QSMerchantLogTransactions:
|
case ServerOP_QSPlayerLogMerchantTransactions: {
|
||||||
{
|
|
||||||
QSMerchantLogTransaction_Struct *QS = (QSMerchantLogTransaction_Struct*)pack->pBuffer;
|
QSMerchantLogTransaction_Struct *QS = (QSMerchantLogTransaction_Struct*)pack->pBuffer;
|
||||||
uint32 Items = QS->char_count + QS->merchant_count;
|
uint32 Items = QS->char_count + QS->merchant_count;
|
||||||
database.LogMerchantTransaction(QS, Items);
|
database.LogMerchantTransaction(QS, Items);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ServerOP_QueryServGeneric:
|
case ServerOP_QueryServGeneric: {
|
||||||
{
|
/*
|
||||||
// The purpose of ServerOP_QueryServerGeneric is so that we don't have to add code to world just to relay packets
|
The purpose of ServerOP_QueryServerGeneric is so that we don't have to add code to world just to relay packets
|
||||||
// each time we add functionality to queryserv.
|
each time we add functionality to queryserv.
|
||||||
//
|
|
||||||
// A ServerOP_QueryServGeneric packet has the following format:
|
A ServerOP_QueryServGeneric packet has the following format:
|
||||||
//
|
|
||||||
// uint32 SourceZoneID
|
uint32 SourceZoneID
|
||||||
// uint32 SourceInstanceID
|
uint32 SourceInstanceID
|
||||||
// char OriginatingCharacterName[0] // Null terminated name of the character this packet came from. This could be just
|
char OriginatingCharacterName[0]
|
||||||
// // an empty string if it has no meaning in the context of a particular packet.
|
- Null terminated name of the character this packet came from. This could be just
|
||||||
// uint32 Type
|
- an empty string if it has no meaning in the context of a particular packet.
|
||||||
//
|
uint32 Type
|
||||||
// The 'Type' field is a 'sub-opcode'. A value of 0 is used for the LFGuild packets. The next feature to be added
|
|
||||||
// to queryserv would use 1, etc.
|
The 'Type' field is a 'sub-opcode'. A value of 0 is used for the LFGuild packets. The next feature to be added
|
||||||
//
|
to queryserv would use 1, etc.
|
||||||
// Obviously, any fields in the packet following the 'Type' will be unique to the particular type of packet. The
|
|
||||||
// 'Generic' in the name of this ServerOP code relates to the four header fields.
|
Obviously, any fields in the packet following the 'Type' will be unique to the particular type of packet. The
|
||||||
|
'Generic' in the name of this ServerOP code relates to the four header fields.
|
||||||
|
*/
|
||||||
|
|
||||||
char From[64];
|
char From[64];
|
||||||
pack->SetReadPosition(8);
|
pack->SetReadPosition(8);
|
||||||
pack->ReadString(From);
|
pack->ReadString(From);
|
||||||
uint32 Type = pack->ReadUInt32();
|
uint32 Type = pack->ReadUInt32();
|
||||||
|
|
||||||
switch(Type)
|
switch(Type) {
|
||||||
{
|
case QSG_LFGuild:{
|
||||||
case QSG_LFGuild:
|
lfguildmanager.HandlePacket(pack);
|
||||||
{
|
|
||||||
lfguildmanager.HandlePacket(pack);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
_log(QUERYSERV__ERROR, "Received unhandled ServerOP_QueryServGeneric", Type);
|
_log(QUERYSERV__ERROR, "Received unhandled ServerOP_QueryServGeneric", Type);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case ServerOP_QSSendQuery: {
|
||||||
|
/* Process all packets here */
|
||||||
|
database.GeneralQueryReceive(pack);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
safe_delete(pack);
|
safe_delete(pack);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,23 @@
|
|||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for qs_player_events
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `qs_player_events`;
|
||||||
|
CREATE TABLE `qs_player_events` (
|
||||||
|
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
||||||
|
`char_id` int(11) DEFAULT '0',
|
||||||
|
`event` int(11) unsigned DEFAULT '0',
|
||||||
|
`event_desc` varchar(255) DEFAULT NULL,
|
||||||
|
`time` int(11) unsigned DEFAULT '0',
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for qs_player_aa_rate_hourly
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `qs_player_aa_rate_hourly`;
|
||||||
|
CREATE TABLE `qs_player_aa_rate_hourly` (
|
||||||
|
`char_id` int(11) NOT NULL DEFAULT '0',
|
||||||
|
`hour_time` int(11) NOT NULL,
|
||||||
|
`aa_count` varchar(11) DEFAULT NULL,
|
||||||
|
PRIMARY KEY (`char_id`,`hour_time`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||||
@ -0,0 +1,45 @@
|
|||||||
|
-- Disable Player Logging for All --
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogPCCoordinates', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogNPCKills', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogTrades', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogMerchantTransactions', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogDeletes', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogHandins', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogMoves', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogChat', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogKeyringAddition', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogAAPurchases', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogIssuedCommandes', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogMoneyTransactions', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogAlternateCurrencyTransactions', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogTradeSkillEvents', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogPCCoordinates', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogDropItem', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogMerchantTransactions', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogDeletes', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogHandins', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogMoves', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogNPCKills', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogTrades', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogQGlobalUpdate', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogTaskUpdates', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogDeaths', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogZone', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogConnectDisconnect', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogLevels', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogAARate', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogChat', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogDropItem', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogZone', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogDeaths', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogLevels', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogEXPRate', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogAARate', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogQGlobalUpdate', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogTaskUpdates', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogKeyringAddition', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogAAPurchases', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogTradeSkillEvents', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogIssuedCommandes', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogMoneyTransactions', 'false', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogAlternateCurrencyTransactions', 'false', '');
|
||||||
@ -0,0 +1,45 @@
|
|||||||
|
-- Enable Player Logging for All --
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogPCCoordinates', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogNPCKills', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogTrades', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogMerchantTransactions', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogDeletes', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogHandins', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogMoves', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogChat', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogKeyringAddition', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogAAPurchases', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogIssuedCommandes', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogMoneyTransactions', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogAlternateCurrencyTransactions', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogTradeSkillEvents', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogPCCoordinates', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogDropItem', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogMerchantTransactions', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogDeletes', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogHandins', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogMoves', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogNPCKills', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogTrades', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogQGlobalUpdate', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogTaskUpdates', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogDeaths', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogZone', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogConnectDisconnect', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogLevels', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (9, 'QueryServ:PlayerLogAARate', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogChat', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogDropItem', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogZone', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogDeaths', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogLevels', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogEXPRate', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogAARate', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogQGlobalUpdate', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogTaskUpdates', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogKeyringAddition', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogAAPurchases', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogTradeSkillEvents', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogIssuedCommandes', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogMoneyTransactions', 'true', '');
|
||||||
|
REPLACE INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (0, 'QueryServ:PlayerLogAlternateCurrencyTransactions', 'true', '');
|
||||||
@ -0,0 +1,247 @@
|
|||||||
|
-- QS Table Structures --
|
||||||
|
|
||||||
|
SET FOREIGN_KEY_CHECKS=0;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for qs_merchant_transaction_record
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `qs_merchant_transaction_record`;
|
||||||
|
CREATE TABLE `qs_merchant_transaction_record` (
|
||||||
|
`transaction_id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`time` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
|
||||||
|
`zone_id` int(11) DEFAULT '0',
|
||||||
|
`merchant_id` int(11) DEFAULT '0',
|
||||||
|
`merchant_pp` int(11) DEFAULT '0',
|
||||||
|
`merchant_gp` int(11) DEFAULT '0',
|
||||||
|
`merchant_sp` int(11) DEFAULT '0',
|
||||||
|
`merchant_cp` int(11) DEFAULT '0',
|
||||||
|
`merchant_items` mediumint(7) DEFAULT '0',
|
||||||
|
`char_id` int(11) DEFAULT '0',
|
||||||
|
`char_pp` int(11) DEFAULT '0',
|
||||||
|
`char_gp` int(11) DEFAULT '0',
|
||||||
|
`char_sp` int(11) DEFAULT '0',
|
||||||
|
`char_cp` int(11) DEFAULT '0',
|
||||||
|
`char_items` mediumint(7) DEFAULT '0',
|
||||||
|
PRIMARY KEY (`transaction_id`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for qs_merchant_transaction_record_entries
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `qs_merchant_transaction_record_entries`;
|
||||||
|
CREATE TABLE `qs_merchant_transaction_record_entries` (
|
||||||
|
`event_id` int(11) DEFAULT '0',
|
||||||
|
`char_slot` mediumint(7) DEFAULT '0',
|
||||||
|
`item_id` int(11) DEFAULT '0',
|
||||||
|
`charges` mediumint(7) DEFAULT '0',
|
||||||
|
`aug_1` int(11) DEFAULT '0',
|
||||||
|
`aug_2` int(11) DEFAULT '0',
|
||||||
|
`aug_3` int(11) DEFAULT '0',
|
||||||
|
`aug_4` int(11) DEFAULT '0',
|
||||||
|
`aug_5` int(11) DEFAULT '0'
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for qs_player_aa_rate_hourly
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `qs_player_aa_rate_hourly`;
|
||||||
|
CREATE TABLE `qs_player_aa_rate_hourly` (
|
||||||
|
`char_id` int(11) NOT NULL DEFAULT '0',
|
||||||
|
`hour_time` int(11) NOT NULL,
|
||||||
|
`aa_count` varchar(11) DEFAULT NULL,
|
||||||
|
PRIMARY KEY (`char_id`,`hour_time`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for qs_player_delete_record
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `qs_player_delete_record`;
|
||||||
|
CREATE TABLE `qs_player_delete_record` (
|
||||||
|
`delete_id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`time` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
|
||||||
|
`char_id` int(11) DEFAULT '0',
|
||||||
|
`stack_size` mediumint(7) DEFAULT '0',
|
||||||
|
`char_items` mediumint(7) DEFAULT '0',
|
||||||
|
PRIMARY KEY (`delete_id`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for qs_player_delete_record_entries
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `qs_player_delete_record_entries`;
|
||||||
|
CREATE TABLE `qs_player_delete_record_entries` (
|
||||||
|
`event_id` int(11) DEFAULT '0',
|
||||||
|
`char_slot` mediumint(7) DEFAULT '0',
|
||||||
|
`item_id` int(11) DEFAULT '0',
|
||||||
|
`charges` mediumint(7) DEFAULT '0',
|
||||||
|
`aug_1` int(11) DEFAULT '0',
|
||||||
|
`aug_2` int(11) DEFAULT '0',
|
||||||
|
`aug_3` int(11) DEFAULT '0',
|
||||||
|
`aug_4` int(11) DEFAULT '0',
|
||||||
|
`aug_5` int(11) DEFAULT '0'
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for qs_player_events
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `qs_player_events`;
|
||||||
|
CREATE TABLE `qs_player_events` (
|
||||||
|
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
||||||
|
`char_id` int(11) DEFAULT '0',
|
||||||
|
`event` int(11) unsigned DEFAULT '0',
|
||||||
|
`event_desc` varchar(255) DEFAULT NULL,
|
||||||
|
`time` int(11) unsigned DEFAULT '0',
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for qs_player_handin_record
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `qs_player_handin_record`;
|
||||||
|
CREATE TABLE `qs_player_handin_record` (
|
||||||
|
`handin_id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`time` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
|
||||||
|
`quest_id` int(11) DEFAULT '0',
|
||||||
|
`char_id` int(11) DEFAULT '0',
|
||||||
|
`char_pp` int(11) DEFAULT '0',
|
||||||
|
`char_gp` int(11) DEFAULT '0',
|
||||||
|
`char_sp` int(11) DEFAULT '0',
|
||||||
|
`char_cp` int(11) DEFAULT '0',
|
||||||
|
`char_items` mediumint(7) DEFAULT '0',
|
||||||
|
`npc_id` int(11) DEFAULT '0',
|
||||||
|
`npc_pp` int(11) DEFAULT '0',
|
||||||
|
`npc_gp` int(11) DEFAULT '0',
|
||||||
|
`npc_sp` int(11) DEFAULT '0',
|
||||||
|
`npc_cp` int(11) DEFAULT '0',
|
||||||
|
`npc_items` mediumint(7) DEFAULT '0',
|
||||||
|
PRIMARY KEY (`handin_id`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for qs_player_handin_record_entries
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `qs_player_handin_record_entries`;
|
||||||
|
CREATE TABLE `qs_player_handin_record_entries` (
|
||||||
|
`event_id` int(11) DEFAULT '0',
|
||||||
|
`action_type` char(6) DEFAULT 'action',
|
||||||
|
`char_slot` mediumint(7) DEFAULT '0',
|
||||||
|
`item_id` int(11) DEFAULT '0',
|
||||||
|
`charges` mediumint(7) DEFAULT '0',
|
||||||
|
`aug_1` int(11) DEFAULT '0',
|
||||||
|
`aug_2` int(11) DEFAULT '0',
|
||||||
|
`aug_3` int(11) DEFAULT '0',
|
||||||
|
`aug_4` int(11) DEFAULT '0',
|
||||||
|
`aug_5` int(11) DEFAULT '0'
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for qs_player_move_record
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `qs_player_move_record`;
|
||||||
|
CREATE TABLE `qs_player_move_record` (
|
||||||
|
`move_id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`time` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
|
||||||
|
`char_id` int(11) DEFAULT '0',
|
||||||
|
`from_slot` mediumint(7) DEFAULT '0',
|
||||||
|
`to_slot` mediumint(7) DEFAULT '0',
|
||||||
|
`stack_size` mediumint(7) DEFAULT '0',
|
||||||
|
`char_items` mediumint(7) DEFAULT '0',
|
||||||
|
`postaction` tinyint(1) DEFAULT '0',
|
||||||
|
PRIMARY KEY (`move_id`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for qs_player_move_record_entries
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `qs_player_move_record_entries`;
|
||||||
|
CREATE TABLE `qs_player_move_record_entries` (
|
||||||
|
`event_id` int(11) DEFAULT '0',
|
||||||
|
`from_slot` mediumint(7) DEFAULT '0',
|
||||||
|
`to_slot` mediumint(7) DEFAULT '0',
|
||||||
|
`item_id` int(11) DEFAULT '0',
|
||||||
|
`charges` mediumint(7) DEFAULT '0',
|
||||||
|
`aug_1` int(11) DEFAULT '0',
|
||||||
|
`aug_2` int(11) DEFAULT '0',
|
||||||
|
`aug_3` int(11) DEFAULT '0',
|
||||||
|
`aug_4` int(11) DEFAULT '0',
|
||||||
|
`aug_5` int(11) DEFAULT '0'
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for qs_player_npc_kill_record
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `qs_player_npc_kill_record`;
|
||||||
|
CREATE TABLE `qs_player_npc_kill_record` (
|
||||||
|
`fight_id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`npc_id` int(11) DEFAULT NULL,
|
||||||
|
`type` int(11) DEFAULT NULL,
|
||||||
|
`zone_id` int(11) DEFAULT NULL,
|
||||||
|
`time` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
|
||||||
|
PRIMARY KEY (`fight_id`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for qs_player_npc_kill_record_entries
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `qs_player_npc_kill_record_entries`;
|
||||||
|
CREATE TABLE `qs_player_npc_kill_record_entries` (
|
||||||
|
`event_id` int(11) DEFAULT '0',
|
||||||
|
`char_id` int(11) DEFAULT '0'
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for qs_player_speech
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `qs_player_speech`;
|
||||||
|
CREATE TABLE `qs_player_speech` (
|
||||||
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`from` varchar(64) NOT NULL,
|
||||||
|
`to` varchar(64) NOT NULL,
|
||||||
|
`message` varchar(256) NOT NULL,
|
||||||
|
`minstatus` smallint(5) NOT NULL,
|
||||||
|
`guilddbid` int(11) NOT NULL,
|
||||||
|
`type` tinyint(3) NOT NULL,
|
||||||
|
`timerecorded` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for qs_player_trade_record
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `qs_player_trade_record`;
|
||||||
|
CREATE TABLE `qs_player_trade_record` (
|
||||||
|
`trade_id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`time` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
|
||||||
|
`char1_id` int(11) DEFAULT '0',
|
||||||
|
`char1_pp` int(11) DEFAULT '0',
|
||||||
|
`char1_gp` int(11) DEFAULT '0',
|
||||||
|
`char1_sp` int(11) DEFAULT '0',
|
||||||
|
`char1_cp` int(11) DEFAULT '0',
|
||||||
|
`char1_items` mediumint(7) DEFAULT '0',
|
||||||
|
`char2_id` int(11) DEFAULT '0',
|
||||||
|
`char2_pp` int(11) DEFAULT '0',
|
||||||
|
`char2_gp` int(11) DEFAULT '0',
|
||||||
|
`char2_sp` int(11) DEFAULT '0',
|
||||||
|
`char2_cp` int(11) DEFAULT '0',
|
||||||
|
`char2_items` mediumint(7) DEFAULT '0',
|
||||||
|
PRIMARY KEY (`trade_id`)
|
||||||
|
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for qs_player_trade_record_entries
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `qs_player_trade_record_entries`;
|
||||||
|
CREATE TABLE `qs_player_trade_record_entries` (
|
||||||
|
`event_id` int(11) DEFAULT '0',
|
||||||
|
`from_id` int(11) DEFAULT '0',
|
||||||
|
`from_slot` mediumint(7) DEFAULT '0',
|
||||||
|
`to_id` int(11) DEFAULT '0',
|
||||||
|
`to_slot` mediumint(7) DEFAULT '0',
|
||||||
|
`item_id` int(11) DEFAULT '0',
|
||||||
|
`charges` mediumint(7) DEFAULT '0',
|
||||||
|
`aug_1` int(11) DEFAULT '0',
|
||||||
|
`aug_2` int(11) DEFAULT '0',
|
||||||
|
`aug_3` int(11) DEFAULT '0',
|
||||||
|
`aug_4` int(11) DEFAULT '0',
|
||||||
|
`aug_5` int(11) DEFAULT '0'
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||||
33
utils/sql/git/required/2014_08_24_character_lookup.sql
Normal file
33
utils/sql/git/required/2014_08_24_character_lookup.sql
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
-- chracter_lookup table structure --
|
||||||
|
|
||||||
|
CREATE TABLE `character_lookup` (
|
||||||
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`account_id` int(11) NOT NULL DEFAULT '0',
|
||||||
|
`name` varchar(64) NOT NULL DEFAULT '',
|
||||||
|
`timelaston` int(11) unsigned DEFAULT '0',
|
||||||
|
`x` float NOT NULL DEFAULT '0',
|
||||||
|
`y` float NOT NULL DEFAULT '0',
|
||||||
|
`z` float NOT NULL DEFAULT '0',
|
||||||
|
`zonename` varchar(30) NOT NULL DEFAULT '',
|
||||||
|
`zoneid` smallint(6) NOT NULL DEFAULT '0',
|
||||||
|
`instanceid` smallint(5) unsigned NOT NULL DEFAULT '0',
|
||||||
|
`pktime` int(8) NOT NULL DEFAULT '0',
|
||||||
|
`groupid` int(10) unsigned NOT NULL DEFAULT '0',
|
||||||
|
`class` tinyint(4) NOT NULL DEFAULT '0',
|
||||||
|
`level` mediumint(8) unsigned NOT NULL DEFAULT '0',
|
||||||
|
`lfp` tinyint(1) unsigned NOT NULL DEFAULT '0',
|
||||||
|
`lfg` tinyint(1) unsigned NOT NULL DEFAULT '0',
|
||||||
|
`mailkey` char(16) NOT NULL,
|
||||||
|
`xtargets` tinyint(3) unsigned NOT NULL DEFAULT '5',
|
||||||
|
`firstlogon` tinyint(3) NOT NULL DEFAULT '0',
|
||||||
|
`inspectmessage` varchar(256) NOT NULL DEFAULT '',
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
UNIQUE KEY `name` (`name`),
|
||||||
|
KEY `account_id` (`account_id`)
|
||||||
|
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;
|
||||||
|
|
||||||
|
-- Initial population of the character_lookup table --
|
||||||
|
|
||||||
|
INSERT INTO `character_lookup` (id, account_id, `name`, timelaston, x, y, z, zonename, zoneid, instanceid, pktime, groupid, class, `level`, lfp, lfg, mailkey, xtargets, firstlogon, inspectmessage)
|
||||||
|
SELECT id, account_id, `name`, timelaston, x, y, z, zonename, zoneid, instanceid, pktime, groupid, class, `level`, lfp, lfg, mailkey, xtargets, firstlogon, inspectmessage
|
||||||
|
FROM `character_`;
|
||||||
@ -1268,7 +1268,7 @@ bool ZoneServer::Process() {
|
|||||||
UCSLink.SendPacket(pack);
|
UCSLink.SendPacket(pack);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case ServerOP_QSSendQuery:
|
||||||
case ServerOP_QueryServGeneric:
|
case ServerOP_QueryServGeneric:
|
||||||
case ServerOP_Speech:
|
case ServerOP_Speech:
|
||||||
case ServerOP_QSPlayerLogTrades:
|
case ServerOP_QSPlayerLogTrades:
|
||||||
@ -1296,7 +1296,7 @@ bool ZoneServer::Process() {
|
|||||||
QSLink.SendPacket(pack);
|
QSLink.SendPacket(pack);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ServerOP_QSMerchantLogTransactions:
|
case ServerOP_QSPlayerLogMerchantTransactions:
|
||||||
{
|
{
|
||||||
QSLink.SendPacket(pack);
|
QSLink.SendPacket(pack);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -16,7 +16,7 @@ SET(zone_sources
|
|||||||
command.cpp
|
command.cpp
|
||||||
corpse.cpp
|
corpse.cpp
|
||||||
doors.cpp
|
doors.cpp
|
||||||
effects.cpp
|
effects.cpp
|
||||||
embparser.cpp
|
embparser.cpp
|
||||||
embparser_api.cpp
|
embparser_api.cpp
|
||||||
embperl.cpp
|
embperl.cpp
|
||||||
@ -93,6 +93,7 @@ SET(zone_sources
|
|||||||
petitions.cpp
|
petitions.cpp
|
||||||
pets.cpp
|
pets.cpp
|
||||||
qglobals.cpp
|
qglobals.cpp
|
||||||
|
queryserv.cpp
|
||||||
questmgr.cpp
|
questmgr.cpp
|
||||||
quest_parser_collection.cpp
|
quest_parser_collection.cpp
|
||||||
raids.cpp
|
raids.cpp
|
||||||
@ -184,6 +185,8 @@ SET(zone_headers
|
|||||||
pets.h
|
pets.h
|
||||||
qglobals.h
|
qglobals.h
|
||||||
quest_interface.h
|
quest_interface.h
|
||||||
|
queryserv.h
|
||||||
|
quest_interface.h
|
||||||
questmgr.h
|
questmgr.h
|
||||||
quest_parser_collection.h
|
quest_parser_collection.h
|
||||||
raid.h
|
raid.h
|
||||||
|
|||||||
39
zone/aa.cpp
39
zone/aa.cpp
@ -38,6 +38,9 @@ Copyright (C) 2001-2004 EQEMu Development Team (http://eqemulator.net)
|
|||||||
#include "../common/logsys.h"
|
#include "../common/logsys.h"
|
||||||
#include "zonedb.h"
|
#include "zonedb.h"
|
||||||
#include "string_ids.h"
|
#include "string_ids.h"
|
||||||
|
#include "queryserv.h"
|
||||||
|
|
||||||
|
extern QueryServ* QServ;
|
||||||
|
|
||||||
//static data arrays, really not big enough to warrant shared mem.
|
//static data arrays, really not big enough to warrant shared mem.
|
||||||
AA_DBAction AA_Actions[aaHighestID][MAX_AA_ACTION_RANKS]; //[aaid][rank]
|
AA_DBAction AA_Actions[aaHighestID][MAX_AA_ACTION_RANKS]; //[aaid][rank]
|
||||||
@ -1039,16 +1042,16 @@ void Client::BuyAA(AA_Action* action)
|
|||||||
else
|
else
|
||||||
real_cost = aa2->cost + (aa2->cost_inc * cur_level);
|
real_cost = aa2->cost + (aa2->cost_inc * cur_level);
|
||||||
|
|
||||||
if(m_pp.aapoints >= real_cost && cur_level < aa2->max_level) {
|
if (m_pp.aapoints >= real_cost && cur_level < aa2->max_level) {
|
||||||
SetAA(aa2->id, cur_level+1);
|
SetAA(aa2->id, cur_level + 1);
|
||||||
|
|
||||||
mlog(AA__MESSAGE, "Set AA %d to level %d", aa2->id, cur_level+1);
|
mlog(AA__MESSAGE, "Set AA %d to level %d", aa2->id, cur_level + 1);
|
||||||
|
|
||||||
m_pp.aapoints -= real_cost;
|
m_pp.aapoints -= real_cost;
|
||||||
|
|
||||||
Save();
|
Save();
|
||||||
if ((RuleB(AA, Stacking) && (GetClientVersionBit() >= 4) && (aa2->hotkey_sid == 4294967295u))
|
if ((RuleB(AA, Stacking) && (GetClientVersionBit() >= 4) && (aa2->hotkey_sid == 4294967295u))
|
||||||
&& ((aa2->max_level == (cur_level+1)) && aa2->sof_next_id)){
|
&& ((aa2->max_level == (cur_level + 1)) && aa2->sof_next_id)){
|
||||||
SendAA(aa2->id);
|
SendAA(aa2->id);
|
||||||
SendAA(aa2->sof_next_id);
|
SendAA(aa2->sof_next_id);
|
||||||
}
|
}
|
||||||
@ -1059,10 +1062,28 @@ void Client::BuyAA(AA_Action* action)
|
|||||||
|
|
||||||
//we are building these messages ourself instead of using the stringID to work around patch discrepencies
|
//we are building these messages ourself instead of using the stringID to work around patch discrepencies
|
||||||
//these are AA_GAIN_ABILITY (410) & AA_IMPROVE (411), respectively, in both Titanium & SoF. not sure about 6.2
|
//these are AA_GAIN_ABILITY (410) & AA_IMPROVE (411), respectively, in both Titanium & SoF. not sure about 6.2
|
||||||
if(cur_level<1)
|
|
||||||
Message(15,"You have gained the ability \"%s\" at a cost of %d ability %s.", aa2->name, real_cost, (real_cost>1)?"points":"point");
|
/* Initial purchase of an AA ability */
|
||||||
else
|
if (cur_level < 1){
|
||||||
Message(15,"You have improved %s %d at a cost of %d ability %s.", aa2->name, cur_level+1, real_cost, (real_cost>1)?"points":"point");
|
Message(15, "You have gained the ability \"%s\" at a cost of %d ability %s.", aa2->name, real_cost, (real_cost>1) ? "points" : "point");
|
||||||
|
|
||||||
|
/* QS: Player_Log_AA_Purchases */
|
||||||
|
if (RuleB(QueryServ, PlayerLogAAPurchases)){
|
||||||
|
std::string event_desc = StringFormat("Initial AA Purchase :: aa_name:%s aa_id:%i at cost:%i in zoneid:%i instid:%i", aa2->name, aa2->id, real_cost, this->GetZoneID(), this->GetInstanceID());
|
||||||
|
QServ->PlayerLogEvent(Player_Log_AA_Purchases, this->CharacterID(), event_desc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Ranked purchase of an AA ability */
|
||||||
|
else{
|
||||||
|
Message(15, "You have improved %s %d at a cost of %d ability %s.", aa2->name, cur_level + 1, real_cost, (real_cost > 1) ? "points" : "point");
|
||||||
|
|
||||||
|
/* QS: Player_Log_AA_Purchases */
|
||||||
|
if (RuleB(QueryServ, PlayerLogAAPurchases)){
|
||||||
|
std::string event_desc = StringFormat("Ranked AA Purchase :: aa_name:%s aa_id:%i at cost:%i in zoneid:%i instid:%i", aa2->name, aa2->id, real_cost, this->GetZoneID(), this->GetInstanceID());
|
||||||
|
QServ->PlayerLogEvent(Player_Log_AA_Purchases, this->CharacterID(), event_desc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
SendAAStats();
|
SendAAStats();
|
||||||
@ -1816,7 +1837,7 @@ SendAA_Struct* ZoneDatabase::GetAASkillVars(uint32 skill_id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
query = StringFormat("SELECT a.cost, a.max_level, a.hotkey_sid, a.hotkey_sid2, a.title_sid, a.desc_sid, a.type, "
|
query = StringFormat("SELECT a.cost, a.max_level, a.hotkey_sid, a.hotkey_sid2, a.title_sid, a.desc_sid, a.type, "
|
||||||
"COALESCE (" //So we can return 0 if it's null.
|
"COALESCE(" //So we can return 0 if it's null.
|
||||||
"(" // this is our derived table that has the row #
|
"(" // this is our derived table that has the row #
|
||||||
// that we can SELECT from, because the client is stupid.
|
// that we can SELECT from, because the client is stupid.
|
||||||
"SELECT p.prereq_index_num "
|
"SELECT p.prereq_index_num "
|
||||||
|
|||||||
@ -873,7 +873,30 @@ bool Mob::CombatRange(Mob* other)
|
|||||||
if (size_mod > 10000)
|
if (size_mod > 10000)
|
||||||
size_mod = size_mod / 7;
|
size_mod = size_mod / 7;
|
||||||
|
|
||||||
if (DistNoRoot(*other) <= size_mod)
|
float _DistNoRoot = DistNoRoot(*other);
|
||||||
|
|
||||||
|
if (GetSpecialAbility(NPC_CHASE_DISTANCE)){
|
||||||
|
|
||||||
|
float max_dist = static_cast<float>(GetSpecialAbilityParam(NPC_CHASE_DISTANCE, 0));
|
||||||
|
float min_dist = static_cast<float>(GetSpecialAbilityParam(NPC_CHASE_DISTANCE, 1));
|
||||||
|
|
||||||
|
if (max_dist == 1)
|
||||||
|
max_dist = 250.0f; //Default it to 250 if you forget to put a value
|
||||||
|
|
||||||
|
max_dist = max_dist * max_dist;
|
||||||
|
|
||||||
|
if (!min_dist)
|
||||||
|
min_dist = size_mod; //Default to melee range
|
||||||
|
else
|
||||||
|
min_dist = min_dist * min_dist;
|
||||||
|
|
||||||
|
if (CheckLastLosState() && (_DistNoRoot >= min_dist && _DistNoRoot <= max_dist))
|
||||||
|
SetPseudoRoot(true);
|
||||||
|
else
|
||||||
|
SetPseudoRoot(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_DistNoRoot <= size_mod)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -887,6 +910,8 @@ bool Mob::CheckLosFN(Mob* other) {
|
|||||||
if(other)
|
if(other)
|
||||||
Result = CheckLosFN(other->GetX(), other->GetY(), other->GetZ(), other->GetSize());
|
Result = CheckLosFN(other->GetX(), other->GetY(), other->GetZ(), other->GetSize());
|
||||||
|
|
||||||
|
SetLastLosState(Result);
|
||||||
|
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -42,6 +42,9 @@
|
|||||||
#include "quest_parser_collection.h"
|
#include "quest_parser_collection.h"
|
||||||
#include "water_map.h"
|
#include "water_map.h"
|
||||||
#include "worldserver.h"
|
#include "worldserver.h"
|
||||||
|
#include "queryserv.h"
|
||||||
|
|
||||||
|
extern QueryServ* QServ;
|
||||||
extern WorldServer worldserver;
|
extern WorldServer worldserver;
|
||||||
|
|
||||||
#ifdef _WINDOWS
|
#ifdef _WINDOWS
|
||||||
@ -1455,14 +1458,14 @@ bool Client::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes att
|
|||||||
int exploss = 0;
|
int exploss = 0;
|
||||||
mlog(COMBAT__HITS, "Fatal blow dealt by %s with %d damage, spell %d, skill %d", killerMob ? killerMob->GetName() : "Unknown", damage, spell, attack_skill);
|
mlog(COMBAT__HITS, "Fatal blow dealt by %s with %d damage, spell %d, skill %d", killerMob ? killerMob->GetName() : "Unknown", damage, spell, attack_skill);
|
||||||
|
|
||||||
//
|
/*
|
||||||
// #1: Send death packet to everyone
|
#1: Send death packet to everyone
|
||||||
//
|
*/
|
||||||
uint8 killed_level = GetLevel();
|
uint8 killed_level = GetLevel();
|
||||||
|
|
||||||
SendLogoutPackets();
|
SendLogoutPackets();
|
||||||
|
|
||||||
//make our become corpse packet, and queue to ourself before OP_Death.
|
/* Make self become corpse packet */
|
||||||
EQApplicationPacket app2(OP_BecomeCorpse, sizeof(BecomeCorpse_Struct));
|
EQApplicationPacket app2(OP_BecomeCorpse, sizeof(BecomeCorpse_Struct));
|
||||||
BecomeCorpse_Struct* bc = (BecomeCorpse_Struct*)app2.pBuffer;
|
BecomeCorpse_Struct* bc = (BecomeCorpse_Struct*)app2.pBuffer;
|
||||||
bc->spawn_id = GetID();
|
bc->spawn_id = GetID();
|
||||||
@ -1471,7 +1474,7 @@ bool Client::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes att
|
|||||||
bc->z = GetZ();
|
bc->z = GetZ();
|
||||||
QueuePacket(&app2);
|
QueuePacket(&app2);
|
||||||
|
|
||||||
// make death packet
|
/* Make Death Packet */
|
||||||
EQApplicationPacket app(OP_Death, sizeof(Death_Struct));
|
EQApplicationPacket app(OP_Death, sizeof(Death_Struct));
|
||||||
Death_Struct* d = (Death_Struct*)app.pBuffer;
|
Death_Struct* d = (Death_Struct*)app.pBuffer;
|
||||||
d->spawn_id = GetID();
|
d->spawn_id = GetID();
|
||||||
@ -1484,9 +1487,9 @@ bool Client::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes att
|
|||||||
app.priority = 6;
|
app.priority = 6;
|
||||||
entity_list.QueueClients(this, &app);
|
entity_list.QueueClients(this, &app);
|
||||||
|
|
||||||
//
|
/*
|
||||||
// #2: figure out things that affect the player dying and mark them dead
|
#2: figure out things that affect the player dying and mark them dead
|
||||||
//
|
*/
|
||||||
|
|
||||||
InterruptSpell();
|
InterruptSpell();
|
||||||
SetPet(0);
|
SetPet(0);
|
||||||
@ -1541,9 +1544,9 @@ bool Client::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes att
|
|||||||
//remove ourself from all proximities
|
//remove ourself from all proximities
|
||||||
ClearAllProximities();
|
ClearAllProximities();
|
||||||
|
|
||||||
//
|
/*
|
||||||
// #3: exp loss and corpse generation
|
#3: exp loss and corpse generation
|
||||||
//
|
*/
|
||||||
|
|
||||||
// figure out if they should lose exp
|
// figure out if they should lose exp
|
||||||
if(RuleB(Character, UseDeathExpLossMult)){
|
if(RuleB(Character, UseDeathExpLossMult)){
|
||||||
@ -1659,27 +1662,21 @@ bool Client::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes att
|
|||||||
|
|
||||||
LeftCorpse = true;
|
LeftCorpse = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if(!IsLD())//Todo: make it so an LDed client leaves corpse if its enabled
|
|
||||||
// MakeCorpse(exploss);
|
|
||||||
} else {
|
} else {
|
||||||
BuffFadeDetrimental();
|
BuffFadeDetrimental();
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
/*
|
||||||
// Finally, send em home
|
Finally, send em home
|
||||||
//
|
|
||||||
|
|
||||||
// we change the mob variables, not pp directly, because Save() will copy
|
We change the mob variables, not pp directly, because Save() will copy
|
||||||
// from these and overwrite what we set in pp anyway
|
from these and overwrite what we set in pp anyway
|
||||||
//
|
*/
|
||||||
|
|
||||||
if(LeftCorpse && (GetClientVersionBit() & BIT_SoFAndLater) && RuleB(Character, RespawnFromHover))
|
if(LeftCorpse && (GetClientVersionBit() & BIT_SoFAndLater) && RuleB(Character, RespawnFromHover))
|
||||||
{
|
{
|
||||||
ClearDraggedCorpses();
|
ClearDraggedCorpses();
|
||||||
|
RespawnFromHoverTimer.Start(RuleI(Character, RespawnFromHoverTimer) * 1000);
|
||||||
RespawnFromHoverTimer.Start(RuleI(Character, RespawnFromHoverTimer) * 1000);
|
|
||||||
|
|
||||||
SendRespawnBinds();
|
SendRespawnBinds();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1696,17 +1693,22 @@ bool Client::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes att
|
|||||||
if(r)
|
if(r)
|
||||||
r->MemberZoned(this);
|
r->MemberZoned(this);
|
||||||
|
|
||||||
dead_timer.Start(5000, true);
|
dead_timer.Start(5000, true);
|
||||||
|
|
||||||
m_pp.zone_id = m_pp.binds[0].zoneId;
|
m_pp.zone_id = m_pp.binds[0].zoneId;
|
||||||
m_pp.zoneInstance = 0;
|
m_pp.zoneInstance = 0;
|
||||||
database.MoveCharacterToZone(this->CharacterID(), database.GetZoneName(m_pp.zone_id));
|
database.MoveCharacterToZone(this->CharacterID(), database.GetZoneName(m_pp.zone_id));
|
||||||
|
Save();
|
||||||
Save();
|
|
||||||
|
|
||||||
GoToDeath();
|
GoToDeath();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* QS: PlayerLogDeaths */
|
||||||
|
if (RuleB(QueryServ, PlayerLogDeaths)){
|
||||||
|
const char * killer_name = "";
|
||||||
|
if (killerMob && killerMob->GetCleanName()){ killer_name = killerMob->GetCleanName(); }
|
||||||
|
std::string event_desc = StringFormat("Died in zoneid:%i instid:%i by '%s', spellid:%i, damage:%i", this->GetZoneID(), this->GetInstanceID(), killer_name, spell, damage);
|
||||||
|
QServ->PlayerLogEvent(Player_Log_Deaths, this->CharacterID(), event_desc);
|
||||||
|
}
|
||||||
|
|
||||||
parse->EventPlayer(EVENT_DEATH_COMPLETE, this, buffer, 0);
|
parse->EventPlayer(EVENT_DEATH_COMPLETE, this, buffer, 0);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -62,8 +62,9 @@ extern volatile bool RunLoops;
|
|||||||
#include "client_logs.h"
|
#include "client_logs.h"
|
||||||
#include "guild_mgr.h"
|
#include "guild_mgr.h"
|
||||||
#include "quest_parser_collection.h"
|
#include "quest_parser_collection.h"
|
||||||
|
#include "queryserv.h"
|
||||||
|
|
||||||
|
extern QueryServ* QServ;
|
||||||
extern EntityList entity_list;
|
extern EntityList entity_list;
|
||||||
extern Zone* zone;
|
extern Zone* zone;
|
||||||
extern volatile bool ZoneLoaded;
|
extern volatile bool ZoneLoaded;
|
||||||
@ -629,6 +630,9 @@ bool Client::Save(uint8 iCommitNow) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Mirror Character Data */
|
||||||
|
database.StoreCharacterLookup(this->CharacterID());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -805,8 +809,8 @@ void Client::ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_s
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Logs Player Chat */
|
||||||
if(RuleB(QueryServ, PlayerChatLogging)) {
|
if (RuleB(QueryServ, PlayerLogChat)) {
|
||||||
ServerPacket* pack = new ServerPacket(ServerOP_Speech, sizeof(Server_Speech_Struct) + strlen(message) + 1);
|
ServerPacket* pack = new ServerPacket(ServerOP_Speech, sizeof(Server_Speech_Struct) + strlen(message) + 1);
|
||||||
Server_Speech_Struct* sem = (Server_Speech_Struct*) pack->pBuffer;
|
Server_Speech_Struct* sem = (Server_Speech_Struct*) pack->pBuffer;
|
||||||
|
|
||||||
@ -841,7 +845,7 @@ void Client::ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_s
|
|||||||
|
|
||||||
switch(chan_num)
|
switch(chan_num)
|
||||||
{
|
{
|
||||||
case 0: { // GuildChat
|
case 0: { /* Guild Chat */
|
||||||
if (!IsInAGuild())
|
if (!IsInAGuild())
|
||||||
Message_StringID(MT_DefaultText, GUILD_NOT_MEMBER2); //You are not a member of any guild.
|
Message_StringID(MT_DefaultText, GUILD_NOT_MEMBER2); //You are not a member of any guild.
|
||||||
else if (!guild_mgr.CheckPermission(GuildID(), GuildRank(), GUILD_SPEAK))
|
else if (!guild_mgr.CheckPermission(GuildID(), GuildRank(), GUILD_SPEAK))
|
||||||
@ -850,7 +854,7 @@ void Client::ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_s
|
|||||||
Message(0, "Error: World server disconnected");
|
Message(0, "Error: World server disconnected");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 2: { // GroupChat
|
case 2: { /* Group Chat */
|
||||||
Raid* raid = entity_list.GetRaidByClient(this);
|
Raid* raid = entity_list.GetRaidByClient(this);
|
||||||
if(raid) {
|
if(raid) {
|
||||||
raid->RaidGroupSay((const char*) message, this);
|
raid->RaidGroupSay((const char*) message, this);
|
||||||
@ -863,14 +867,14 @@ void Client::ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_s
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 15: { //raid say
|
case 15: { /* Raid Say */
|
||||||
Raid* raid = entity_list.GetRaidByClient(this);
|
Raid* raid = entity_list.GetRaidByClient(this);
|
||||||
if(raid){
|
if(raid){
|
||||||
raid->RaidSay((const char*) message, this);
|
raid->RaidSay((const char*) message, this);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 3: { // Shout
|
case 3: { /* Shout */
|
||||||
Mob *sender = this;
|
Mob *sender = this;
|
||||||
if (GetPet() && GetPet()->FindType(SE_VoiceGraft))
|
if (GetPet() && GetPet()->FindType(SE_VoiceGraft))
|
||||||
sender = GetPet();
|
sender = GetPet();
|
||||||
@ -878,7 +882,7 @@ void Client::ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_s
|
|||||||
entity_list.ChannelMessage(sender, chan_num, language, lang_skill, message);
|
entity_list.ChannelMessage(sender, chan_num, language, lang_skill, message);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 4: { // Auction
|
case 4: { /* Auction */
|
||||||
if(RuleB(Chat, ServerWideAuction))
|
if(RuleB(Chat, ServerWideAuction))
|
||||||
{
|
{
|
||||||
if(!global_channel_timer.Check())
|
if(!global_channel_timer.Check())
|
||||||
@ -917,7 +921,7 @@ void Client::ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_s
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 5: { // OOC
|
case 5: { /* OOC */
|
||||||
if(RuleB(Chat, ServerWideOOC))
|
if(RuleB(Chat, ServerWideOOC))
|
||||||
{
|
{
|
||||||
if(!global_channel_timer.Check())
|
if(!global_channel_timer.Check())
|
||||||
@ -964,15 +968,15 @@ void Client::ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_s
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 6: // Broadcast
|
case 6: /* Broadcast */
|
||||||
case 11: { // GMSay
|
case 11: { /* GM Say */
|
||||||
if (!(admin >= 80))
|
if (!(admin >= 80))
|
||||||
Message(0, "Error: Only GMs can use this channel");
|
Message(0, "Error: Only GMs can use this channel");
|
||||||
else if (!worldserver.SendChannelMessage(this, targetname, chan_num, 0, language, message))
|
else if (!worldserver.SendChannelMessage(this, targetname, chan_num, 0, language, message))
|
||||||
Message(0, "Error: World server disconnected");
|
Message(0, "Error: World server disconnected");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 7: { // Tell
|
case 7: { /* Tell */
|
||||||
if(!global_channel_timer.Check())
|
if(!global_channel_timer.Check())
|
||||||
{
|
{
|
||||||
if(strlen(targetname) == 0)
|
if(strlen(targetname) == 0)
|
||||||
@ -1020,7 +1024,7 @@ void Client::ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_s
|
|||||||
Message(0, "Error: World server disconnected");
|
Message(0, "Error: World server disconnected");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 8: { // /say
|
case 8: { /* Say */
|
||||||
if(message[0] == COMMAND_CHAR) {
|
if(message[0] == COMMAND_CHAR) {
|
||||||
if(command_dispatch(this, message) == -2) {
|
if(command_dispatch(this, message) == -2) {
|
||||||
if(parse->PlayerHasQuestSub(EVENT_COMMAND)) {
|
if(parse->PlayerHasQuestSub(EVENT_COMMAND)) {
|
||||||
@ -4029,13 +4033,17 @@ void Client::KeyRingAdd(uint32 item_id)
|
|||||||
bool bFound = KeyRingCheck(item_id);
|
bool bFound = KeyRingCheck(item_id);
|
||||||
if(!bFound){
|
if(!bFound){
|
||||||
sprintf(query, "INSERT INTO keyring(char_id,item_id) VALUES(%i,%i)",character_id,item_id);
|
sprintf(query, "INSERT INTO keyring(char_id,item_id) VALUES(%i,%i)",character_id,item_id);
|
||||||
if(database.RunQuery(query, strlen(query), errbuf, 0, &affected_rows))
|
if(database.RunQuery(query, strlen(query), errbuf, 0, &affected_rows)) {
|
||||||
{
|
|
||||||
Message(4,"Added to keyring.");
|
Message(4,"Added to keyring.");
|
||||||
|
|
||||||
|
/* QS: PlayerLogKeyringAddition */
|
||||||
|
if (RuleB(QueryServ, PlayerLogKeyringAddition)){
|
||||||
|
std::string event_desc = StringFormat("itemid:%i in zoneid:%i instid:%i", item_id, this->GetZoneID(), this->GetInstanceID());
|
||||||
|
QServ->PlayerLogEvent(Player_Log_Keyring_Addition, this->CharacterID(), event_desc);
|
||||||
|
}
|
||||||
safe_delete_array(query);
|
safe_delete_array(query);
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
std::cerr << "Error in Doors::HandleClick query '" << query << "' " << errbuf << std::endl;
|
std::cerr << "Error in Doors::HandleClick query '" << query << "' " << errbuf << std::endl;
|
||||||
safe_delete_array(query);
|
safe_delete_array(query);
|
||||||
return;
|
return;
|
||||||
@ -6933,8 +6941,18 @@ void Client::SetAlternateCurrencyValue(uint32 currency_id, uint32 new_amount)
|
|||||||
SendAlternateCurrencyValue(currency_id);
|
SendAlternateCurrencyValue(currency_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::AddAlternateCurrencyValue(uint32 currency_id, int32 amount)
|
void Client::AddAlternateCurrencyValue(uint32 currency_id, int32 amount, int8 method)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/* Added via Quest, rest of the logging methods may be done inline due to information available in that area of the code */
|
||||||
|
if (method == 1){
|
||||||
|
/* QS: PlayerLogAlternateCurrencyTransactions :: Cursor to Item Storage */
|
||||||
|
if (RuleB(QueryServ, PlayerLogAlternateCurrencyTransactions)){
|
||||||
|
std::string event_desc = StringFormat("Added via Quest :: Cursor to Item :: alt_currency_id:%i amount:%i in zoneid:%i instid:%i", currency_id, this->GetZoneID(), this->GetInstanceID());
|
||||||
|
QServ->PlayerLogEvent(Player_Log_Alternate_Currency_Transactions, this->CharacterID(), event_desc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(amount == 0) {
|
if(amount == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1097,7 +1097,7 @@ public:
|
|||||||
inline void ClearDraggedCorpses() { DraggedCorpses.clear(); }
|
inline void ClearDraggedCorpses() { DraggedCorpses.clear(); }
|
||||||
void SendAltCurrencies();
|
void SendAltCurrencies();
|
||||||
void SetAlternateCurrencyValue(uint32 currency_id, uint32 new_amount);
|
void SetAlternateCurrencyValue(uint32 currency_id, uint32 new_amount);
|
||||||
void AddAlternateCurrencyValue(uint32 currency_id, int32 amount);
|
void AddAlternateCurrencyValue(uint32 currency_id, int32 amount, int8 method = 0);
|
||||||
void SendAlternateCurrencyValues();
|
void SendAlternateCurrencyValues();
|
||||||
void SendAlternateCurrencyValue(uint32 currency_id, bool send_if_null = true);
|
void SendAlternateCurrencyValue(uint32 currency_id, bool send_if_null = true);
|
||||||
uint32 GetAlternateCurrencyValue(uint32 currency_id) const;
|
uint32 GetAlternateCurrencyValue(uint32 currency_id) const;
|
||||||
|
|||||||
@ -16,16 +16,16 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "../common/debug.h"
|
#include "../common/debug.h"
|
||||||
#include <iostream>
|
|
||||||
#include <iomanip>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <math.h>
|
|
||||||
#include <zlib.h>
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <sstream>
|
#include <iomanip>
|
||||||
|
#include <iostream>
|
||||||
|
#include <math.h>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
#include <sstream>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <zlib.h>
|
||||||
|
|
||||||
#ifdef _WINDOWS
|
#ifdef _WINDOWS
|
||||||
#define snprintf _snprintf
|
#define snprintf _snprintf
|
||||||
@ -38,8 +38,6 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "masterentity.h"
|
|
||||||
#include "zonedb.h"
|
|
||||||
#include "../common/packet_functions.h"
|
#include "../common/packet_functions.h"
|
||||||
#include "../common/packet_dump.h"
|
#include "../common/packet_dump.h"
|
||||||
#include "worldserver.h"
|
#include "worldserver.h"
|
||||||
@ -59,17 +57,21 @@
|
|||||||
#include "../common/faction.h"
|
#include "../common/faction.h"
|
||||||
#include "../common/crc32.h"
|
#include "../common/crc32.h"
|
||||||
#include "string_ids.h"
|
#include "string_ids.h"
|
||||||
#include "map.h"
|
|
||||||
#include "titles.h"
|
#include "titles.h"
|
||||||
#include "pets.h"
|
#include "water_map.h"
|
||||||
|
#include "worldserver.h"
|
||||||
|
#include "zone.h"
|
||||||
#include "zone_config.h"
|
#include "zone_config.h"
|
||||||
#include "guild_mgr.h"
|
#include "guild_mgr.h"
|
||||||
#include "pathing.h"
|
#include "pathing.h"
|
||||||
#include "water_map.h"
|
#include "water_map.h"
|
||||||
#include "merc.h"
|
#include "merc.h"
|
||||||
|
#include "pets.h"
|
||||||
#include "../common/zone_numbers.h"
|
#include "../common/zone_numbers.h"
|
||||||
#include "quest_parser_collection.h"
|
#include "quest_parser_collection.h"
|
||||||
|
#include "queryserv.h"
|
||||||
|
|
||||||
|
extern QueryServ* QServ;
|
||||||
extern Zone* zone;
|
extern Zone* zone;
|
||||||
extern volatile bool ZoneLoaded;
|
extern volatile bool ZoneLoaded;
|
||||||
extern WorldServer worldserver;
|
extern WorldServer worldserver;
|
||||||
@ -5687,8 +5689,8 @@ void Client::Handle_OP_ShopPlayerBuy(const EQApplicationPacket *app)
|
|||||||
safe_delete(outapp);
|
safe_delete(outapp);
|
||||||
|
|
||||||
// start QS code
|
// start QS code
|
||||||
if(RuleB(QueryServ, MerchantLogTransactions)) {
|
if(RuleB(QueryServ, PlayerLogMerchantTransactions)) {
|
||||||
ServerPacket* qspack = new ServerPacket(ServerOP_QSMerchantLogTransactions, sizeof(QSMerchantLogTransaction_Struct) + sizeof(QSTransactionItems_Struct));
|
ServerPacket* qspack = new ServerPacket(ServerOP_QSPlayerLogMerchantTransactions, sizeof(QSMerchantLogTransaction_Struct) + sizeof(QSTransactionItems_Struct));
|
||||||
QSMerchantLogTransaction_Struct* qsaudit = (QSMerchantLogTransaction_Struct*)qspack->pBuffer;
|
QSMerchantLogTransaction_Struct* qsaudit = (QSMerchantLogTransaction_Struct*)qspack->pBuffer;
|
||||||
|
|
||||||
qsaudit->zone_id = zone->GetZoneID();
|
qsaudit->zone_id = zone->GetZoneID();
|
||||||
@ -5823,8 +5825,8 @@ void Client::Handle_OP_ShopPlayerSell(const EQApplicationPacket *app)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// start QS code
|
// start QS code
|
||||||
if(RuleB(QueryServ, MerchantLogTransactions)) {
|
if(RuleB(QueryServ, PlayerLogMerchantTransactions)) {
|
||||||
ServerPacket* qspack = new ServerPacket(ServerOP_QSMerchantLogTransactions, sizeof(QSMerchantLogTransaction_Struct) + sizeof(QSTransactionItems_Struct));
|
ServerPacket* qspack = new ServerPacket(ServerOP_QSPlayerLogMerchantTransactions, sizeof(QSMerchantLogTransaction_Struct) + sizeof(QSTransactionItems_Struct));
|
||||||
QSMerchantLogTransaction_Struct* qsaudit = (QSMerchantLogTransaction_Struct*)qspack->pBuffer;
|
QSMerchantLogTransaction_Struct* qsaudit = (QSMerchantLogTransaction_Struct*)qspack->pBuffer;
|
||||||
|
|
||||||
qsaudit->zone_id = zone->GetZoneID();
|
qsaudit->zone_id = zone->GetZoneID();
|
||||||
@ -9180,8 +9182,7 @@ bool Client::FinishConnState2(DBAsyncWork* dbaw) {
|
|||||||
if(!GetAA(aaPersistentMinion))
|
if(!GetAA(aaPersistentMinion))
|
||||||
memset(&m_suspendedminion, 0, sizeof(PetInfo));
|
memset(&m_suspendedminion, 0, sizeof(PetInfo));
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
/* Server Zone Entry Packet */
|
||||||
// Server Zone Entry Packet
|
|
||||||
outapp = new EQApplicationPacket(OP_ZoneEntry, sizeof(ServerZoneEntry_Struct));
|
outapp = new EQApplicationPacket(OP_ZoneEntry, sizeof(ServerZoneEntry_Struct));
|
||||||
ServerZoneEntry_Struct* sze = (ServerZoneEntry_Struct*)outapp->pBuffer;
|
ServerZoneEntry_Struct* sze = (ServerZoneEntry_Struct*)outapp->pBuffer;
|
||||||
|
|
||||||
@ -9191,43 +9192,31 @@ bool Client::FinishConnState2(DBAsyncWork* dbaw) {
|
|||||||
sze->player.spawn.z += 6; //arbitrary lift, seems to help spawning under zone.
|
sze->player.spawn.z += 6; //arbitrary lift, seems to help spawning under zone.
|
||||||
outapp->priority = 6;
|
outapp->priority = 6;
|
||||||
FastQueuePacket(&outapp);
|
FastQueuePacket(&outapp);
|
||||||
//safe_delete(outapp);
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
/* Zone Spawns Packet */
|
||||||
// Zone Spawns Packet
|
|
||||||
entity_list.SendZoneSpawnsBulk(this);
|
entity_list.SendZoneSpawnsBulk(this);
|
||||||
entity_list.SendZoneCorpsesBulk(this);
|
entity_list.SendZoneCorpsesBulk(this);
|
||||||
entity_list.SendZonePVPUpdates(this); //hack until spawn struct is fixed.
|
entity_list.SendZonePVPUpdates(this); //hack until spawn struct is fixed.
|
||||||
|
|
||||||
|
/* Time of Day packet */
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
// Time of Day packet
|
|
||||||
outapp = new EQApplicationPacket(OP_TimeOfDay, sizeof(TimeOfDay_Struct));
|
outapp = new EQApplicationPacket(OP_TimeOfDay, sizeof(TimeOfDay_Struct));
|
||||||
TimeOfDay_Struct* tod = (TimeOfDay_Struct*)outapp->pBuffer;
|
TimeOfDay_Struct* tod = (TimeOfDay_Struct*)outapp->pBuffer;
|
||||||
zone->zone_time.getEQTimeOfDay(time(0), tod);
|
zone->zone_time.getEQTimeOfDay(time(0), tod);
|
||||||
outapp->priority = 6;
|
outapp->priority = 6;
|
||||||
FastQueuePacket(&outapp);
|
FastQueuePacket(&outapp);
|
||||||
//safe_delete(outapp);
|
|
||||||
|
|
||||||
//I think this should happen earlier, not sure
|
/* Tribute Packets */
|
||||||
/* if(GetHideMe())
|
|
||||||
SetHideMe(true); */
|
|
||||||
// Moved to Handle_Connect_OP_SendExpZonein();
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
// Tribute Packets
|
|
||||||
DoTributeUpdate();
|
DoTributeUpdate();
|
||||||
if(m_pp.tribute_active) {
|
if(m_pp.tribute_active) {
|
||||||
//restart the tribute timer where we left off
|
//restart the tribute timer where we left off
|
||||||
tribute_timer.Start(m_pp.tribute_time_remaining);
|
tribute_timer.Start(m_pp.tribute_time_remaining);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
/*
|
||||||
// Character Inventory Packet
|
Character Inventory Packet
|
||||||
//this is not quite where live sends inventory, they do it after tribute
|
this is not quite where live sends inventory, they do it after tribute
|
||||||
if (loaditems) {//dont load if a length error occurs
|
*/
|
||||||
|
if (loaditems) { //dont load if a length error occurs
|
||||||
BulkSendInventoryItems();
|
BulkSendInventoryItems();
|
||||||
|
|
||||||
// Send stuff on the cursor which isnt sent in bulk
|
// Send stuff on the cursor which isnt sent in bulk
|
||||||
@ -9241,9 +9230,7 @@ bool Client::FinishConnState2(DBAsyncWork* dbaw) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Task Packets */
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
// Task Packets
|
|
||||||
LoadClientTaskState();
|
LoadClientTaskState();
|
||||||
|
|
||||||
if (GetClientVersion() >= EQClientRoF)
|
if (GetClientVersion() >= EQClientRoF)
|
||||||
@ -9261,10 +9248,11 @@ bool Client::FinishConnState2(DBAsyncWork* dbaw) {
|
|||||||
FastQueuePacket(&outapp);
|
FastQueuePacket(&outapp);
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////
|
/*
|
||||||
// Weather Packet
|
Weather Packet
|
||||||
// This shouldent be moved, this seems to be what the client
|
This shouldent be moved, this seems to be what the client
|
||||||
// uses to advance to the next state (sending ReqNewZone)
|
uses to advance to the next state (sending ReqNewZone)
|
||||||
|
*/
|
||||||
outapp = new EQApplicationPacket(OP_Weather, 12);
|
outapp = new EQApplicationPacket(OP_Weather, 12);
|
||||||
Weather_Struct *ws = (Weather_Struct *) outapp->pBuffer;
|
Weather_Struct *ws = (Weather_Struct *) outapp->pBuffer;
|
||||||
ws->val1 = 0x000000FF;
|
ws->val1 = 0x000000FF;
|
||||||
@ -9279,16 +9267,6 @@ bool Client::FinishConnState2(DBAsyncWork* dbaw) {
|
|||||||
QueuePacket(outapp);
|
QueuePacket(outapp);
|
||||||
safe_delete(outapp);
|
safe_delete(outapp);
|
||||||
|
|
||||||
//////////////////////////////////////
|
|
||||||
// Group Roles
|
|
||||||
//
|
|
||||||
//////////////////////////////////////
|
|
||||||
/*if(group){
|
|
||||||
group->NotifyMainTank(this, 1);
|
|
||||||
group->NotifyMainAssist(this, 1);
|
|
||||||
group->NotifyPuller(this, 1);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
SetAttackTimer();
|
SetAttackTimer();
|
||||||
|
|
||||||
conn_state = ZoneInfoSent;
|
conn_state = ZoneInfoSent;
|
||||||
@ -9296,9 +9274,8 @@ bool Client::FinishConnState2(DBAsyncWork* dbaw) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finish client connecting state
|
/* Finish client connecting state */
|
||||||
void Client::CompleteConnect()
|
void Client::CompleteConnect() {
|
||||||
{
|
|
||||||
UpdateWho();
|
UpdateWho();
|
||||||
client_state = CLIENT_CONNECTED;
|
client_state = CLIENT_CONNECTED;
|
||||||
|
|
||||||
@ -9311,14 +9288,14 @@ void Client::CompleteConnect()
|
|||||||
EnteringMessages(this);
|
EnteringMessages(this);
|
||||||
LoadZoneFlags();
|
LoadZoneFlags();
|
||||||
|
|
||||||
// Sets GM Flag if needed & Sends Petition Queue
|
/* Sets GM Flag if needed & Sends Petition Queue */
|
||||||
UpdateAdmin(false);
|
UpdateAdmin(false);
|
||||||
|
|
||||||
if(IsInAGuild()){
|
if (IsInAGuild()){
|
||||||
SendAppearancePacket(AT_GuildID, GuildID(), false);
|
SendAppearancePacket(AT_GuildID, GuildID(), false);
|
||||||
SendAppearancePacket(AT_GuildRank, GuildRank(), false);
|
SendAppearancePacket(AT_GuildRank, GuildRank(), false);
|
||||||
}
|
}
|
||||||
for(uint32 spellInt= 0; spellInt < MAX_PP_SPELLBOOK; spellInt++)
|
for (uint32 spellInt = 0; spellInt < MAX_PP_SPELLBOOK; spellInt++)
|
||||||
{
|
{
|
||||||
if (m_pp.spell_book[spellInt] < 3 || m_pp.spell_book[spellInt] > 50000)
|
if (m_pp.spell_book[spellInt] < 3 || m_pp.spell_book[spellInt] > 50000)
|
||||||
m_pp.spell_book[spellInt] = 0xFFFFFFFF;
|
m_pp.spell_book[spellInt] = 0xFFFFFFFF;
|
||||||
@ -9329,35 +9306,37 @@ void Client::CompleteConnect()
|
|||||||
|
|
||||||
uint32 raidid = database.GetRaidID(GetName());
|
uint32 raidid = database.GetRaidID(GetName());
|
||||||
Raid *raid = nullptr;
|
Raid *raid = nullptr;
|
||||||
if(raidid > 0){
|
if (raidid > 0){
|
||||||
raid = entity_list.GetRaidByID(raidid);
|
raid = entity_list.GetRaidByID(raidid);
|
||||||
if(!raid){
|
if (!raid){
|
||||||
raid = new Raid(raidid);
|
raid = new Raid(raidid);
|
||||||
if(raid->GetID() != 0){
|
if (raid->GetID() != 0){
|
||||||
entity_list.AddRaid(raid, raidid);
|
entity_list.AddRaid(raid, raidid);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
raid = nullptr;
|
raid = nullptr;
|
||||||
}
|
}
|
||||||
if(raid){
|
if (raid){
|
||||||
SetRaidGrouped(true);
|
SetRaidGrouped(true);
|
||||||
raid->LearnMembers();
|
raid->LearnMembers();
|
||||||
raid->VerifyRaid();
|
raid->VerifyRaid();
|
||||||
raid->GetRaidDetails();
|
raid->GetRaidDetails();
|
||||||
//only leader should get this; send to all for now till
|
/*
|
||||||
//I figure out correct creation; can probably also send a no longer leader packet for non leaders
|
Only leader should get this; send to all for now till
|
||||||
//but not important for now.
|
I figure out correct creation; can probably also send a no longer leader packet for non leaders
|
||||||
|
but not important for now.
|
||||||
|
*/
|
||||||
raid->SendRaidCreate(this);
|
raid->SendRaidCreate(this);
|
||||||
raid->SendMakeLeaderPacketTo(raid->leadername, this);
|
raid->SendMakeLeaderPacketTo(raid->leadername, this);
|
||||||
raid->SendRaidAdd(GetName(), this);
|
raid->SendRaidAdd(GetName(), this);
|
||||||
raid->SendBulkRaid(this);
|
raid->SendBulkRaid(this);
|
||||||
raid->SendGroupUpdate(this);
|
raid->SendGroupUpdate(this);
|
||||||
uint32 grpID = raid->GetGroup(GetName());
|
uint32 grpID = raid->GetGroup(GetName());
|
||||||
if(grpID < 12){
|
if (grpID < 12){
|
||||||
raid->SendRaidGroupRemove(GetName(), grpID);
|
raid->SendRaidGroupRemove(GetName(), grpID);
|
||||||
raid->SendRaidGroupAdd(GetName(), grpID);
|
raid->SendRaidGroupAdd(GetName(), grpID);
|
||||||
}
|
}
|
||||||
if(raid->IsLocked())
|
if (raid->IsLocked())
|
||||||
raid->SendRaidLockTo(this);
|
raid->SendRaidLockTo(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -9366,154 +9345,155 @@ void Client::CompleteConnect()
|
|||||||
|
|
||||||
//reapply some buffs
|
//reapply some buffs
|
||||||
uint32 buff_count = GetMaxTotalSlots();
|
uint32 buff_count = GetMaxTotalSlots();
|
||||||
for (uint32 j1=0; j1 < buff_count; j1++) {
|
for (uint32 j1 = 0; j1 < buff_count; j1++) {
|
||||||
if (buffs[j1].spellid > (uint32)SPDAT_RECORDS)
|
if (buffs[j1].spellid >(uint32)SPDAT_RECORDS)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const SPDat_Spell_Struct &spell = spells[buffs[j1].spellid];
|
const SPDat_Spell_Struct &spell = spells[buffs[j1].spellid];
|
||||||
|
|
||||||
for (int x1=0; x1 < EFFECT_COUNT; x1++) {
|
for (int x1 = 0; x1 < EFFECT_COUNT; x1++) {
|
||||||
switch (spell.effectid[x1]) {
|
switch (spell.effectid[x1]) {
|
||||||
case SE_IllusionCopy:
|
case SE_IllusionCopy:
|
||||||
case SE_Illusion: {
|
case SE_Illusion: {
|
||||||
if (spell.base[x1] == -1) {
|
if (spell.base[x1] == -1) {
|
||||||
if (gender == 1)
|
if (gender == 1)
|
||||||
gender = 0;
|
gender = 0;
|
||||||
else if (gender == 0)
|
else if (gender == 0)
|
||||||
gender = 1;
|
gender = 1;
|
||||||
SendIllusionPacket(GetRace(), gender, 0xFF, 0xFF);
|
SendIllusionPacket(GetRace(), gender, 0xFF, 0xFF);
|
||||||
}
|
}
|
||||||
else if (spell.base[x1] == -2)
|
else if (spell.base[x1] == -2)
|
||||||
{
|
{
|
||||||
if (GetRace() == 128 || GetRace() == 130 || GetRace() <= 12)
|
if (GetRace() == 128 || GetRace() == 130 || GetRace() <= 12)
|
||||||
SendIllusionPacket(GetRace(), GetGender(), spell.max[x1], spell.max[x1]);
|
SendIllusionPacket(GetRace(), GetGender(), spell.max[x1], spell.max[x1]);
|
||||||
}
|
}
|
||||||
else if (spell.max[x1] > 0)
|
else if (spell.max[x1] > 0)
|
||||||
{
|
{
|
||||||
SendIllusionPacket(spell.base[x1], 0xFF, spell.max[x1], spell.max[x1]);
|
SendIllusionPacket(spell.base[x1], 0xFF, spell.max[x1], spell.max[x1]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SendIllusionPacket(spell.base[x1], 0xFF, 0xFF, 0xFF);
|
SendIllusionPacket(spell.base[x1], 0xFF, 0xFF, 0xFF);
|
||||||
}
|
}
|
||||||
switch(spell.base[x1]){
|
switch (spell.base[x1]){
|
||||||
case OGRE:
|
case OGRE:
|
||||||
SendAppearancePacket(AT_Size, 9);
|
SendAppearancePacket(AT_Size, 9);
|
||||||
break;
|
break;
|
||||||
case TROLL:
|
case TROLL:
|
||||||
SendAppearancePacket(AT_Size, 8);
|
SendAppearancePacket(AT_Size, 8);
|
||||||
break;
|
break;
|
||||||
case VAHSHIR:
|
case VAHSHIR:
|
||||||
case BARBARIAN:
|
case BARBARIAN:
|
||||||
SendAppearancePacket(AT_Size, 7);
|
SendAppearancePacket(AT_Size, 7);
|
||||||
break;
|
break;
|
||||||
case HALF_ELF:
|
case HALF_ELF:
|
||||||
case WOOD_ELF:
|
case WOOD_ELF:
|
||||||
case DARK_ELF:
|
case DARK_ELF:
|
||||||
case FROGLOK:
|
case FROGLOK:
|
||||||
SendAppearancePacket(AT_Size, 5);
|
SendAppearancePacket(AT_Size, 5);
|
||||||
break;
|
break;
|
||||||
case DWARF:
|
case DWARF:
|
||||||
SendAppearancePacket(AT_Size, 4);
|
SendAppearancePacket(AT_Size, 4);
|
||||||
break;
|
break;
|
||||||
case HALFLING:
|
case HALFLING:
|
||||||
case GNOME:
|
case GNOME:
|
||||||
SendAppearancePacket(AT_Size, 3);
|
SendAppearancePacket(AT_Size, 3);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
SendAppearancePacket(AT_Size, 6);
|
SendAppearancePacket(AT_Size, 6);
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SE_SummonHorse: {
|
break;
|
||||||
SummonHorse(buffs[j1].spellid);
|
}
|
||||||
//hasmount = true; //this was false, is that the correct thing?
|
case SE_SummonHorse: {
|
||||||
break;
|
SummonHorse(buffs[j1].spellid);
|
||||||
|
//hasmount = true; //this was false, is that the correct thing?
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SE_Silence:
|
||||||
|
{
|
||||||
|
Silence(true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SE_Amnesia:
|
||||||
|
{
|
||||||
|
Amnesia(true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SE_DivineAura:
|
||||||
|
{
|
||||||
|
invulnerable = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SE_Invisibility2:
|
||||||
|
case SE_Invisibility:
|
||||||
|
{
|
||||||
|
invisible = true;
|
||||||
|
SendAppearancePacket(AT_Invis, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SE_Levitate:
|
||||||
|
{
|
||||||
|
if (!zone->CanLevitate())
|
||||||
|
{
|
||||||
|
if (!GetGM())
|
||||||
|
{
|
||||||
|
SendAppearancePacket(AT_Levitate, 0);
|
||||||
|
BuffFadeByEffect(SE_Levitate);
|
||||||
|
Message(13, "You can't levitate in this zone.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
case SE_Silence:
|
else{
|
||||||
{
|
SendAppearancePacket(AT_Levitate, 2);
|
||||||
Silence(true);
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SE_Amnesia:
|
case SE_InvisVsUndead2:
|
||||||
{
|
case SE_InvisVsUndead:
|
||||||
Amnesia(true);
|
{
|
||||||
break;
|
invisible_undead = true;
|
||||||
}
|
break;
|
||||||
case SE_DivineAura:
|
}
|
||||||
{
|
case SE_InvisVsAnimals:
|
||||||
invulnerable = true;
|
{
|
||||||
break;
|
invisible_animals = true;
|
||||||
}
|
break;
|
||||||
case SE_Invisibility2:
|
}
|
||||||
case SE_Invisibility:
|
case SE_AddMeleeProc:
|
||||||
{
|
case SE_WeaponProc:
|
||||||
invisible = true;
|
{
|
||||||
SendAppearancePacket(AT_Invis, 1);
|
AddProcToWeapon(GetProcID(buffs[j1].spellid, x1), false, 100 + spells[buffs[j1].spellid].base2[x1], buffs[j1].spellid);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SE_Levitate:
|
case SE_DefensiveProc:
|
||||||
{
|
{
|
||||||
if( !zone->CanLevitate() )
|
AddDefensiveProc(GetProcID(buffs[j1].spellid, x1), 100 + spells[buffs[j1].spellid].base2[x1], buffs[j1].spellid);
|
||||||
{
|
break;
|
||||||
if(!GetGM())
|
}
|
||||||
{
|
case SE_RangedProc:
|
||||||
SendAppearancePacket(AT_Levitate, 0);
|
{
|
||||||
BuffFadeByEffect(SE_Levitate);
|
AddRangedProc(GetProcID(buffs[j1].spellid, x1), 100 + spells[buffs[j1].spellid].base2[x1], buffs[j1].spellid);
|
||||||
Message(13, "You can't levitate in this zone.");
|
break;
|
||||||
}
|
}
|
||||||
}else{
|
|
||||||
SendAppearancePacket(AT_Levitate, 2);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SE_InvisVsUndead2:
|
|
||||||
case SE_InvisVsUndead:
|
|
||||||
{
|
|
||||||
invisible_undead = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SE_InvisVsAnimals:
|
|
||||||
{
|
|
||||||
invisible_animals = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SE_AddMeleeProc:
|
|
||||||
case SE_WeaponProc:
|
|
||||||
{
|
|
||||||
AddProcToWeapon(GetProcID(buffs[j1].spellid, x1), false, 100+spells[buffs[j1].spellid].base2[x1], buffs[j1].spellid);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SE_DefensiveProc:
|
|
||||||
{
|
|
||||||
AddDefensiveProc(GetProcID(buffs[j1].spellid, x1), 100+spells[buffs[j1].spellid].base2[x1],buffs[j1].spellid);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SE_RangedProc:
|
|
||||||
{
|
|
||||||
AddRangedProc(GetProcID(buffs[j1].spellid, x1), 100+spells[buffs[j1].spellid].base2[x1],buffs[j1].spellid);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//sends appearances for all mobs not doing anim_stand aka sitting, looting, playing dead
|
/* Sends appearances for all mobs not doing anim_stand aka sitting, looting, playing dead */
|
||||||
entity_list.SendZoneAppearance(this);
|
entity_list.SendZoneAppearance(this);
|
||||||
|
|
||||||
//sends the Nimbus particle effects (up to 3) for any mob using them
|
/* Sends the Nimbus particle effects (up to 3) for any mob using them */
|
||||||
entity_list.SendNimbusEffects(this);
|
entity_list.SendNimbusEffects(this);
|
||||||
|
|
||||||
entity_list.SendUntargetable(this);
|
entity_list.SendUntargetable(this);
|
||||||
|
|
||||||
client_data_loaded = true;
|
client_data_loaded = true;
|
||||||
int x;
|
int x;
|
||||||
for(x=0;x<8;x++)
|
for (x = 0; x < 8; x++)
|
||||||
SendWearChange(x);
|
SendWearChange(x);
|
||||||
Mob *pet = GetPet();
|
Mob *pet = GetPet();
|
||||||
if(pet != nullptr) {
|
if (pet != nullptr) {
|
||||||
for(x=0;x<8;x++)
|
for (x = 0; x < 8; x++)
|
||||||
pet->SendWearChange(x);
|
pet->SendWearChange(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -9521,14 +9501,14 @@ void Client::CompleteConnect()
|
|||||||
|
|
||||||
zoneinpacket_timer.Start();
|
zoneinpacket_timer.Start();
|
||||||
|
|
||||||
if(GetPet()){
|
if (GetPet()){
|
||||||
GetPet()->SendPetBuffsToClient();
|
GetPet()->SendPetBuffsToClient();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(GetGroup())
|
if (GetGroup())
|
||||||
database.RefreshGroupFromDB(this);
|
database.RefreshGroupFromDB(this);
|
||||||
|
|
||||||
if(RuleB(TaskSystem, EnableTaskSystem))
|
if (RuleB(TaskSystem, EnableTaskSystem))
|
||||||
TaskPeriodic_Timer.Start();
|
TaskPeriodic_Timer.Start();
|
||||||
else
|
else
|
||||||
TaskPeriodic_Timer.Disable();
|
TaskPeriodic_Timer.Disable();
|
||||||
@ -9536,51 +9516,50 @@ void Client::CompleteConnect()
|
|||||||
conn_state = ClientConnectFinished;
|
conn_state = ClientConnectFinished;
|
||||||
|
|
||||||
//enforce some rules..
|
//enforce some rules..
|
||||||
if(!CanBeInZone()) {
|
if (!CanBeInZone()) {
|
||||||
_log(CLIENT__ERROR, "Kicking char from zone, not allowed here");
|
_log(CLIENT__ERROR, "Kicking char from zone, not allowed here");
|
||||||
GoToSafeCoords(database.GetZoneID("arena"), 0);
|
GoToSafeCoords(database.GetZoneID("arena"), 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(zone)
|
if (zone)
|
||||||
zone->weatherSend();
|
zone->weatherSend();
|
||||||
|
|
||||||
TotalKarma = database.GetKarma(AccountID());
|
TotalKarma = database.GetKarma(AccountID());
|
||||||
|
|
||||||
SendDisciplineTimers();
|
SendDisciplineTimers();
|
||||||
|
|
||||||
parse->EventPlayer(EVENT_ENTER_ZONE, this, "", 0);
|
parse->EventPlayer(EVENT_ENTER_ZONE, this, "", 0);
|
||||||
|
|
||||||
//This sub event is for if a player logs in for the first time since entering world.
|
/* This sub event is for if a player logs in for the first time since entering world. */
|
||||||
if(firstlogon == 1)
|
if (firstlogon == 1){
|
||||||
parse->EventPlayer(EVENT_CONNECT, this, "", 0);
|
parse->EventPlayer(EVENT_CONNECT, this, "", 0);
|
||||||
|
/* QS: PlayerLogConnectDisconnect */
|
||||||
|
if (RuleB(QueryServ, PlayerLogConnectDisconnect)){
|
||||||
|
std::string event_desc = StringFormat("Connect :: Logged into zoneid:%i instid:%i", this->GetZoneID(), this->GetInstanceID());
|
||||||
|
QServ->PlayerLogEvent(Player_Log_Connect_State, this->CharacterID(), event_desc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(zone)
|
if(zone) {
|
||||||
{
|
if(zone->GetInstanceTimer()) {
|
||||||
if(zone->GetInstanceTimer())
|
|
||||||
{
|
|
||||||
uint32 ttime = zone->GetInstanceTimer()->GetRemainingTime();
|
uint32 ttime = zone->GetInstanceTimer()->GetRemainingTime();
|
||||||
uint32 day = (ttime/86400000);
|
uint32 day = (ttime/86400000);
|
||||||
uint32 hour = (ttime/3600000)%24;
|
uint32 hour = (ttime/3600000)%24;
|
||||||
uint32 minute = (ttime/60000)%60;
|
uint32 minute = (ttime/60000)%60;
|
||||||
uint32 second = (ttime/1000)%60;
|
uint32 second = (ttime/1000)%60;
|
||||||
if(day)
|
if(day) {
|
||||||
{
|
|
||||||
Message(15, "%s(%u) will expire in %u days, %u hours, %u minutes, and %u seconds.",
|
Message(15, "%s(%u) will expire in %u days, %u hours, %u minutes, and %u seconds.",
|
||||||
zone->GetLongName(), zone->GetInstanceID(), day, hour, minute, second);
|
zone->GetLongName(), zone->GetInstanceID(), day, hour, minute, second);
|
||||||
}
|
}
|
||||||
else if(hour)
|
else if(hour) {
|
||||||
{
|
|
||||||
Message(15, "%s(%u) will expire in %u hours, %u minutes, and %u seconds.",
|
Message(15, "%s(%u) will expire in %u hours, %u minutes, and %u seconds.",
|
||||||
zone->GetLongName(), zone->GetInstanceID(), hour, minute, second);
|
zone->GetLongName(), zone->GetInstanceID(), hour, minute, second);
|
||||||
}
|
}
|
||||||
else if(minute)
|
else if(minute) {
|
||||||
{
|
|
||||||
Message(15, "%s(%u) will expire in %u minutes, and %u seconds.",
|
Message(15, "%s(%u) will expire in %u minutes, and %u seconds.",
|
||||||
zone->GetLongName(), zone->GetInstanceID(), minute, second);
|
zone->GetLongName(), zone->GetInstanceID(), minute, second);
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
Message(15, "%s(%u) will expire in in %u seconds.",
|
Message(15, "%s(%u) will expire in in %u seconds.",
|
||||||
zone->GetLongName(), zone->GetInstanceID(), second);
|
zone->GetLongName(), zone->GetInstanceID(), second);
|
||||||
}
|
}
|
||||||
@ -9603,8 +9582,7 @@ void Client::CompleteConnect()
|
|||||||
if(GetClientVersion() >= EQClientSoD)
|
if(GetClientVersion() >= EQClientSoD)
|
||||||
entity_list.SendFindableNPCList(this);
|
entity_list.SendFindableNPCList(this);
|
||||||
|
|
||||||
if(IsInAGuild())
|
if(IsInAGuild()) {
|
||||||
{
|
|
||||||
SendGuildRanks();
|
SendGuildRanks();
|
||||||
guild_mgr.SendGuildMemberUpdateToWorld(GetName(), GuildID(), zone->GetZoneID(), time(nullptr));
|
guild_mgr.SendGuildMemberUpdateToWorld(GetName(), GuildID(), zone->GetZoneID(), time(nullptr));
|
||||||
guild_mgr.RequestOnlineGuildMembers(this->CharacterID(), this->GuildID());
|
guild_mgr.RequestOnlineGuildMembers(this->CharacterID(), this->GuildID());
|
||||||
@ -9616,8 +9594,7 @@ void Client::CompleteConnect()
|
|||||||
worldserver.SendPacket(pack);
|
worldserver.SendPacket(pack);
|
||||||
delete pack;
|
delete pack;
|
||||||
|
|
||||||
if(IsClient() && CastToClient()->GetClientVersionBit() & BIT_UnderfootAndLater)
|
if(IsClient() && CastToClient()->GetClientVersionBit() & BIT_UnderfootAndLater) {
|
||||||
{
|
|
||||||
EQApplicationPacket *outapp = MakeBuffsPacket(false);
|
EQApplicationPacket *outapp = MakeBuffsPacket(false);
|
||||||
CastToClient()->FastQueuePacket(&outapp);
|
CastToClient()->FastQueuePacket(&outapp);
|
||||||
}
|
}
|
||||||
@ -12749,6 +12726,12 @@ void Client::Handle_OP_AltCurrencyPurchase(const EQApplicationPacket *app) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* QS: PlayerLogAlternateCurrencyTransactions :: Merchant Purchase */
|
||||||
|
if (RuleB(QueryServ, PlayerLogAlternateCurrencyTransactions)){
|
||||||
|
std::string event_desc = StringFormat("Merchant Purchase :: Spent alt_currency_id:%i cost:%i for itemid:%i in zoneid:%i instid:%i", alt_cur_id, cost, item->ID, this->GetZoneID(), this->GetInstanceID());
|
||||||
|
QServ->PlayerLogEvent(Player_Log_Alternate_Currency_Transactions, this->CharacterID(), event_desc);
|
||||||
|
}
|
||||||
|
|
||||||
AddAlternateCurrencyValue(alt_cur_id, -((int32)cost));
|
AddAlternateCurrencyValue(alt_cur_id, -((int32)cost));
|
||||||
int16 charges = 1;
|
int16 charges = 1;
|
||||||
if(item->MaxCharges != 0)
|
if(item->MaxCharges != 0)
|
||||||
@ -12780,20 +12763,37 @@ void Client::Handle_OP_AltCurrencyReclaim(const EQApplicationPacket *app) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(reclaim->reclaim_flag == 1) { //item -> altcur
|
/* Item to Currency Storage */
|
||||||
|
if(reclaim->reclaim_flag == 1) {
|
||||||
uint32 removed = NukeItem(item_id, invWhereWorn | invWherePersonal | invWhereCursor);
|
uint32 removed = NukeItem(item_id, invWhereWorn | invWherePersonal | invWhereCursor);
|
||||||
if(removed > 0) {
|
if(removed > 0) {
|
||||||
AddAlternateCurrencyValue(reclaim->currency_id, removed);
|
AddAlternateCurrencyValue(reclaim->currency_id, removed);
|
||||||
|
|
||||||
|
/* QS: PlayerLogAlternateCurrencyTransactions :: Item to Currency */
|
||||||
|
if (RuleB(QueryServ, PlayerLogAlternateCurrencyTransactions)){
|
||||||
|
std::string event_desc = StringFormat("Reclaim :: Item to Currency :: alt_currency_id:%i amount:%i to currency tab in zoneid:%i instid:%i", reclaim->currency_id, removed, this->GetZoneID(), this->GetInstanceID());
|
||||||
|
QServ->PlayerLogEvent(Player_Log_Alternate_Currency_Transactions, this->CharacterID(), event_desc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
/* Cursor to Item storage */
|
||||||
|
else {
|
||||||
uint32 max_currency = GetAlternateCurrencyValue(reclaim->currency_id);
|
uint32 max_currency = GetAlternateCurrencyValue(reclaim->currency_id);
|
||||||
|
|
||||||
|
/* If you input more than you have currency wise, just give the max of the currency you currently have */
|
||||||
if(reclaim->count > max_currency) {
|
if(reclaim->count > max_currency) {
|
||||||
SummonItem(item_id, max_currency);
|
SummonItem(item_id, max_currency);
|
||||||
SetAlternateCurrencyValue(reclaim->currency_id, 0);
|
SetAlternateCurrencyValue(reclaim->currency_id, 0);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
SummonItem(item_id, reclaim->count, 0, 0, 0, 0, 0, false, MainCursor);
|
SummonItem(item_id, reclaim->count, 0, 0, 0, 0, 0, false, MainCursor);
|
||||||
AddAlternateCurrencyValue(reclaim->currency_id, -((int32)reclaim->count));
|
AddAlternateCurrencyValue(reclaim->currency_id, -((int32)reclaim->count));
|
||||||
}
|
}
|
||||||
|
/* QS: PlayerLogAlternateCurrencyTransactions :: Cursor to Item Storage */
|
||||||
|
if (RuleB(QueryServ, PlayerLogAlternateCurrencyTransactions)){
|
||||||
|
std::string event_desc = StringFormat("Reclaim :: Cursor to Item :: alt_currency_id:%i amount:-%i in zoneid:%i instid:%i", reclaim->currency_id, reclaim->count, this->GetZoneID(), this->GetInstanceID());
|
||||||
|
QServ->PlayerLogEvent(Player_Log_Alternate_Currency_Transactions, this->CharacterID(), event_desc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -12829,6 +12829,7 @@ void Client::Handle_OP_AltCurrencySell(const EQApplicationPacket *app) {
|
|||||||
uint32 cost = 0;
|
uint32 cost = 0;
|
||||||
uint32 current_currency = GetAlternateCurrencyValue(alt_cur_id);
|
uint32 current_currency = GetAlternateCurrencyValue(alt_cur_id);
|
||||||
uint32 merchant_id = tar->MerchantType;
|
uint32 merchant_id = tar->MerchantType;
|
||||||
|
uint32 npc_id = tar->GetNPCTypeID();
|
||||||
bool found = false;
|
bool found = false;
|
||||||
std::list<MerchantList> merlist = zone->merchanttable[merchant_id];
|
std::list<MerchantList> merlist = zone->merchanttable[merchant_id];
|
||||||
std::list<MerchantList>::const_iterator itr;
|
std::list<MerchantList>::const_iterator itr;
|
||||||
@ -12881,6 +12882,12 @@ void Client::Handle_OP_AltCurrencySell(const EQApplicationPacket *app) {
|
|||||||
|
|
||||||
sell->cost = cost;
|
sell->cost = cost;
|
||||||
|
|
||||||
|
/* QS: PlayerLogAlternateCurrencyTransactions :: Sold to Merchant*/
|
||||||
|
if (RuleB(QueryServ, PlayerLogAlternateCurrencyTransactions)){
|
||||||
|
std::string event_desc = StringFormat("Sold to Merchant :: itemid:%u npcid:%u alt_currency_id:%u cost:%u in zoneid:%u instid:%i", item->ID, npc_id, alt_cur_id, cost, this->GetZoneID(), this->GetInstanceID());
|
||||||
|
QServ->PlayerLogEvent(Player_Log_Alternate_Currency_Transactions, this->CharacterID(), event_desc);
|
||||||
|
}
|
||||||
|
|
||||||
FastQueuePacket(&outapp);
|
FastQueuePacket(&outapp);
|
||||||
AddAlternateCurrencyValue(alt_cur_id, cost);
|
AddAlternateCurrencyValue(alt_cur_id, cost);
|
||||||
Save(1);
|
Save(1);
|
||||||
@ -12940,7 +12947,7 @@ void Client::Handle_OP_LFGuild(const EQApplicationPacket *app)
|
|||||||
switch(Command)
|
switch(Command)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
{
|
{
|
||||||
VERIFY_PACKET_LENGTH(OP_LFGuild, app, LFGuild_PlayerToggle_Struct);
|
VERIFY_PACKET_LENGTH(OP_LFGuild, app, LFGuild_PlayerToggle_Struct);
|
||||||
LFGuild_PlayerToggle_Struct *pts = (LFGuild_PlayerToggle_Struct *)app->pBuffer;
|
LFGuild_PlayerToggle_Struct *pts = (LFGuild_PlayerToggle_Struct *)app->pBuffer;
|
||||||
|
|
||||||
|
|||||||
@ -63,7 +63,9 @@
|
|||||||
#include "guild_mgr.h"
|
#include "guild_mgr.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "quest_parser_collection.h"
|
#include "quest_parser_collection.h"
|
||||||
|
#include "queryserv.h"
|
||||||
|
|
||||||
|
extern QueryServ* QServ;
|
||||||
extern Zone* zone;
|
extern Zone* zone;
|
||||||
extern volatile bool ZoneLoaded;
|
extern volatile bool ZoneLoaded;
|
||||||
extern WorldServer worldserver;
|
extern WorldServer worldserver;
|
||||||
@ -770,38 +772,40 @@ bool Client::Process() {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
//just a set of actions preformed all over in Client::Process
|
/* Just a set of actions preformed all over in Client::Process */
|
||||||
void Client::OnDisconnect(bool hard_disconnect) {
|
void Client::OnDisconnect(bool hard_disconnect) {
|
||||||
if(hard_disconnect) {
|
if(hard_disconnect) {
|
||||||
LeaveGroup();
|
LeaveGroup();
|
||||||
|
|
||||||
Raid *MyRaid = entity_list.GetRaidByClient(this);
|
Raid *MyRaid = entity_list.GetRaidByClient(this);
|
||||||
|
|
||||||
if (MyRaid)
|
if (MyRaid)
|
||||||
MyRaid->MemberZoned(this);
|
MyRaid->MemberZoned(this);
|
||||||
|
|
||||||
parse->EventPlayer(EVENT_DISCONNECT, this, "", 0);
|
parse->EventPlayer(EVENT_DISCONNECT, this, "", 0);
|
||||||
|
|
||||||
|
/* QS: PlayerLogConnectDisconnect */
|
||||||
|
if (RuleB(QueryServ, PlayerLogConnectDisconnect)){
|
||||||
|
std::string event_desc = StringFormat("Disconnect :: in zoneid:%i instid:%i", this->GetZoneID(), this->GetInstanceID());
|
||||||
|
QServ->PlayerLogEvent(Player_Log_Connect_State, this->CharacterID(), event_desc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Mob *Other = trade->With();
|
Mob *Other = trade->With();
|
||||||
|
if(Other) {
|
||||||
if(Other)
|
mlog(TRADING__CLIENT, "Client disconnected during a trade. Returning their items.");
|
||||||
{
|
|
||||||
mlog(TRADING__CLIENT, "Client disconnected during a trade. Returning their items.");
|
|
||||||
|
|
||||||
FinishTrade(this);
|
FinishTrade(this);
|
||||||
|
|
||||||
if(Other->IsClient())
|
if(Other->IsClient())
|
||||||
Other->CastToClient()->FinishTrade(Other);
|
Other->CastToClient()->FinishTrade(Other);
|
||||||
|
|
||||||
trade->Reset();
|
/* Reset both sides of the trade */
|
||||||
|
trade->Reset();
|
||||||
Other->trade->Reset();
|
Other->trade->Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
database.SetFirstLogon(CharacterID(), 0); //We change firstlogon status regardless of if a player logs out to zone or not, because we only want to trigger it on their first login from world.
|
database.SetFirstLogon(CharacterID(), 0); //We change firstlogon status regardless of if a player logs out to zone or not, because we only want to trigger it on their first login from world.
|
||||||
|
|
||||||
//remove ourself from all proximities
|
/* Remove ourself from all proximities */
|
||||||
ClearAllProximities();
|
ClearAllProximities();
|
||||||
|
|
||||||
EQApplicationPacket *outapp = new EQApplicationPacket(OP_LogoutReply);
|
EQApplicationPacket *outapp = new EQApplicationPacket(OP_LogoutReply);
|
||||||
|
|||||||
@ -62,8 +62,9 @@
|
|||||||
#include "guild_mgr.h"
|
#include "guild_mgr.h"
|
||||||
#include "titles.h"
|
#include "titles.h"
|
||||||
#include "../common/patches/patches.h"
|
#include "../common/patches/patches.h"
|
||||||
|
#include "queryserv.h"
|
||||||
|
|
||||||
// these should be in the headers...
|
extern QueryServ* QServ;
|
||||||
extern WorldServer worldserver;
|
extern WorldServer worldserver;
|
||||||
extern TaskManager *taskmanager;
|
extern TaskManager *taskmanager;
|
||||||
void CatchSignal(int sig_num);
|
void CatchSignal(int sig_num);
|
||||||
@ -588,6 +589,12 @@ int command_realdispatch(Client *c, const char *message)
|
|||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* QS: Player_Log_Issued_Commands */
|
||||||
|
if (RuleB(QueryServ, PlayerLogIssuedCommandes)){
|
||||||
|
std::string event_desc = StringFormat("Issued command :: '%s' in zoneid:%i instid:%i", message, c->GetZoneID(), c->GetInstanceID());
|
||||||
|
QServ->PlayerLogEvent(Player_Log_Issued_Commands, c->CharacterID(), event_desc);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef COMMANDS_LOGGING
|
#ifdef COMMANDS_LOGGING
|
||||||
if(cur->access >= COMMANDS_LOGGING_MIN_STATUS) {
|
if(cur->access >= COMMANDS_LOGGING_MIN_STATUS) {
|
||||||
LogFile->write(EQEMuLog::Commands, "%s (%s) used command: %s (target=%s)", c->GetName(), c->AccountName(), message, c->GetTarget()?c->GetTarget()->GetName():"NONE");
|
LogFile->write(EQEMuLog::Commands, "%s (%s) used command: %s (target=%s)", c->GetName(), c->AccountName(), message, c->GetTarget()?c->GetTarget()->GetName():"NONE");
|
||||||
|
|||||||
@ -127,7 +127,8 @@ enum {
|
|||||||
FLEE_PERCENT = 37,
|
FLEE_PERCENT = 37,
|
||||||
ALLOW_BENEFICIAL = 38,
|
ALLOW_BENEFICIAL = 38,
|
||||||
DISABLE_MELEE = 39,
|
DISABLE_MELEE = 39,
|
||||||
MAX_SPECIAL_ATTACK = 40
|
NPC_CHASE_DISTANCE = 40,
|
||||||
|
MAX_SPECIAL_ATTACK = 41
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -28,8 +28,10 @@
|
|||||||
#include "embxs.h"
|
#include "embxs.h"
|
||||||
#include "entity.h"
|
#include "entity.h"
|
||||||
#include "zone.h"
|
#include "zone.h"
|
||||||
|
#include "queryserv.h"
|
||||||
|
|
||||||
extern Zone* zone;
|
extern Zone* zone;
|
||||||
|
extern QueryServ* QServ;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
@ -3370,6 +3372,36 @@ XS(XS__clear_npctype_cache)
|
|||||||
XSRETURN_EMPTY;
|
XSRETURN_EMPTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XS(XS__qs_send_query);
|
||||||
|
XS(XS__qs_send_query)
|
||||||
|
{
|
||||||
|
dXSARGS;
|
||||||
|
if (items != 1){
|
||||||
|
Perl_croak(aTHX_ "Usage: qs_send_query(query)");
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
// char *Query = (char *)SvPV_nolen(ST(0));
|
||||||
|
std::string Query = (std::string)SvPV_nolen(ST(0));
|
||||||
|
QServ->SendQuery(Query);
|
||||||
|
}
|
||||||
|
XSRETURN_EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
XS(XS__qs_player_event);
|
||||||
|
XS(XS__qs_player_event)
|
||||||
|
{
|
||||||
|
dXSARGS;
|
||||||
|
if (items != 2){
|
||||||
|
Perl_croak(aTHX_ "Usage: qs_player_event(char_id, event_desc)");
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
int char_id = (int)SvIV(ST(0));
|
||||||
|
std::string event_desc = (std::string)SvPV_nolen(ST(1));
|
||||||
|
QServ->PlayerLogEvent(Player_Log_Quest, char_id, event_desc);
|
||||||
|
}
|
||||||
|
XSRETURN_EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This is the callback perl will look for to setup the
|
This is the callback perl will look for to setup the
|
||||||
quest package's XSUBs
|
quest package's XSUBs
|
||||||
@ -3591,6 +3623,8 @@ EXTERN_C XS(boot_quest)
|
|||||||
newXS(strcpy(buf, "enablerecipe"), XS__enablerecipe, file);
|
newXS(strcpy(buf, "enablerecipe"), XS__enablerecipe, file);
|
||||||
newXS(strcpy(buf, "disablerecipe"), XS__disablerecipe, file);
|
newXS(strcpy(buf, "disablerecipe"), XS__disablerecipe, file);
|
||||||
newXS(strcpy(buf, "clear_npctype_cache"), XS__clear_npctype_cache, file);
|
newXS(strcpy(buf, "clear_npctype_cache"), XS__clear_npctype_cache, file);
|
||||||
|
newXS(strcpy(buf, "qs_send_query"), XS__qs_send_query, file);
|
||||||
|
newXS(strcpy(buf, "qs_player_event"), XS__qs_player_event, file);
|
||||||
XSRETURN_YES;
|
XSRETURN_YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -4170,6 +4170,20 @@ void EntityList::SignalAllClients(uint32 data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16 EntityList::GetClientCount(){
|
||||||
|
uint16 ClientCount = 0;
|
||||||
|
std::list<Client*> client_list;
|
||||||
|
entity_list.GetClientList(client_list);
|
||||||
|
std::list<Client*>::iterator iter = client_list.begin();
|
||||||
|
while (iter != client_list.end()) {
|
||||||
|
Client *entry = (*iter);
|
||||||
|
entry->GetCleanName();
|
||||||
|
ClientCount++;
|
||||||
|
iter++;
|
||||||
|
}
|
||||||
|
return ClientCount;
|
||||||
|
}
|
||||||
|
|
||||||
void EntityList::GetMobList(std::list<Mob *> &m_list)
|
void EntityList::GetMobList(std::list<Mob *> &m_list)
|
||||||
{
|
{
|
||||||
m_list.clear();
|
m_list.clear();
|
||||||
|
|||||||
@ -398,6 +398,7 @@ public:
|
|||||||
void UpdateFindableNPCState(NPC *n, bool Remove);
|
void UpdateFindableNPCState(NPC *n, bool Remove);
|
||||||
void HideCorpses(Client *c, uint8 CurrentMode, uint8 NewMode);
|
void HideCorpses(Client *c, uint8 CurrentMode, uint8 NewMode);
|
||||||
|
|
||||||
|
uint16 GetClientCount();
|
||||||
void GetMobList(std::list<Mob*> &m_list);
|
void GetMobList(std::list<Mob*> &m_list);
|
||||||
void GetNPCList(std::list<NPC*> &n_list);
|
void GetNPCList(std::list<NPC*> &n_list);
|
||||||
void GetMercList(std::list<Merc*> &n_list);
|
void GetMercList(std::list<Merc*> &n_list);
|
||||||
|
|||||||
123
zone/exp.cpp
123
zone/exp.cpp
@ -22,6 +22,9 @@
|
|||||||
#include "../common/string_util.h"
|
#include "../common/string_util.h"
|
||||||
#include "../common/rulesys.h"
|
#include "../common/rulesys.h"
|
||||||
#include "quest_parser_collection.h"
|
#include "quest_parser_collection.h"
|
||||||
|
#include "queryserv.h"
|
||||||
|
|
||||||
|
extern QueryServ* QServ;
|
||||||
|
|
||||||
|
|
||||||
static uint32 MaxBankedGroupLeadershipPoints(int Level)
|
static uint32 MaxBankedGroupLeadershipPoints(int Level)
|
||||||
@ -212,7 +215,6 @@ void Client::SetEXP(uint32 set_exp, uint32 set_aaxp, bool isrezzexp) {
|
|||||||
return; // Must be invalid class/race
|
return; // Must be invalid class/race
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if ((set_exp + set_aaxp) > (m_pp.exp+m_pp.expAA)) {
|
if ((set_exp + set_aaxp) > (m_pp.exp+m_pp.expAA)) {
|
||||||
if (isrezzexp)
|
if (isrezzexp)
|
||||||
this->Message_StringID(MT_Experience, REZ_REGAIN);
|
this->Message_StringID(MT_Experience, REZ_REGAIN);
|
||||||
@ -288,6 +290,14 @@ void Client::SetEXP(uint32 set_exp, uint32 set_aaxp, bool isrezzexp) {
|
|||||||
//Message(15, "You have gained %d skill points!!", m_pp.aapoints - last_unspentAA);
|
//Message(15, "You have gained %d skill points!!", m_pp.aapoints - last_unspentAA);
|
||||||
char val1[20]={0};
|
char val1[20]={0};
|
||||||
Message_StringID(MT_Experience, GAIN_ABILITY_POINT,ConvertArray(m_pp.aapoints, val1),m_pp.aapoints == 1 ? "" : "(s)"); //You have gained an ability point! You now have %1 ability point%2.
|
Message_StringID(MT_Experience, GAIN_ABILITY_POINT,ConvertArray(m_pp.aapoints, val1),m_pp.aapoints == 1 ? "" : "(s)"); //You have gained an ability point! You now have %1 ability point%2.
|
||||||
|
|
||||||
|
/* QS: PlayerLogAARate */
|
||||||
|
if (RuleB(QueryServ, PlayerLogAARate)){
|
||||||
|
int add_points = (m_pp.aapoints - last_unspentAA);
|
||||||
|
std::string query = StringFormat("INSERT INTO `qs_player_aa_rate_hourly` (char_id, aa_count, hour_time) VALUES (%i, %i, UNIX_TIMESTAMP() - MOD(UNIX_TIMESTAMP(), 3600)) ON DUPLICATE KEY UPDATE `aa_count` = `aa_count` + %i", this->CharacterID(), add_points, add_points);
|
||||||
|
QServ->SendQuery(query.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
//Message(15, "You now have %d skill points available to spend.", m_pp.aapoints);
|
//Message(15, "You now have %d skill points available to spend.", m_pp.aapoints);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -299,12 +309,10 @@ void Client::SetEXP(uint32 set_exp, uint32 set_aaxp, bool isrezzexp) {
|
|||||||
if(check_level > maxlevel) {
|
if(check_level > maxlevel) {
|
||||||
check_level = maxlevel;
|
check_level = maxlevel;
|
||||||
|
|
||||||
if(RuleB(Character, KeepLevelOverMax))
|
if(RuleB(Character, KeepLevelOverMax)) {
|
||||||
{
|
|
||||||
set_exp = GetEXPForLevel(GetLevel()+1);
|
set_exp = GetEXPForLevel(GetLevel()+1);
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
set_exp = GetEXPForLevel(maxlevel);
|
set_exp = GetEXPForLevel(maxlevel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -314,8 +322,7 @@ void Client::SetEXP(uint32 set_exp, uint32 set_aaxp, bool isrezzexp) {
|
|||||||
if(MaxLevel){
|
if(MaxLevel){
|
||||||
if(GetLevel() >= MaxLevel){
|
if(GetLevel() >= MaxLevel){
|
||||||
uint32 expneeded = GetEXPForLevel(MaxLevel);
|
uint32 expneeded = GetEXPForLevel(MaxLevel);
|
||||||
if(set_exp > expneeded)
|
if(set_exp > expneeded) {
|
||||||
{
|
|
||||||
set_exp = expneeded;
|
set_exp = expneeded;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -327,11 +334,11 @@ void Client::SetEXP(uint32 set_exp, uint32 set_aaxp, bool isrezzexp) {
|
|||||||
if (GetLevel() == check_level-1){
|
if (GetLevel() == check_level-1){
|
||||||
Message_StringID(MT_Experience, GAIN_LEVEL,ConvertArray(check_level,val1));
|
Message_StringID(MT_Experience, GAIN_LEVEL,ConvertArray(check_level,val1));
|
||||||
SendLevelAppearance();
|
SendLevelAppearance();
|
||||||
//Message(15, "You have gained a level! Welcome to level %i!", check_level);
|
/* Message(15, "You have gained a level! Welcome to level %i!", check_level); */
|
||||||
}
|
}
|
||||||
if (GetLevel() == check_level){
|
if (GetLevel() == check_level){
|
||||||
Message_StringID(MT_Experience, LOSE_LEVEL,ConvertArray(check_level,val1));
|
Message_StringID(MT_Experience, LOSE_LEVEL,ConvertArray(check_level,val1));
|
||||||
//Message(15, "You lost a level! You are now level %i!", check_level);
|
/* Message(15, "You lost a level! You are now level %i!", check_level); */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Message(15, "Welcome to level %i!", check_level);
|
Message(15, "Welcome to level %i!", check_level);
|
||||||
@ -352,8 +359,7 @@ void Client::SetEXP(uint32 set_exp, uint32 set_aaxp, bool isrezzexp) {
|
|||||||
//If were at max level then stop gaining experience if we make it to the cap
|
//If were at max level then stop gaining experience if we make it to the cap
|
||||||
if(GetLevel() == maxlevel - 1){
|
if(GetLevel() == maxlevel - 1){
|
||||||
uint32 expneeded = GetEXPForLevel(maxlevel);
|
uint32 expneeded = GetEXPForLevel(maxlevel);
|
||||||
if(set_exp > expneeded)
|
if(set_exp > expneeded) {
|
||||||
{
|
|
||||||
set_exp = expneeded;
|
set_exp = expneeded;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -405,15 +411,13 @@ void Client::SetLevel(uint8 set_level, bool command)
|
|||||||
|
|
||||||
level = set_level;
|
level = set_level;
|
||||||
|
|
||||||
if(IsRaidGrouped())
|
if(IsRaidGrouped()) {
|
||||||
{
|
|
||||||
Raid *r = this->GetRaid();
|
Raid *r = this->GetRaid();
|
||||||
if(r){
|
if(r){
|
||||||
r->UpdateLevel(GetName(), set_level);
|
r->UpdateLevel(GetName(), set_level);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(set_level > m_pp.level2)
|
if(set_level > m_pp.level2) {
|
||||||
{
|
|
||||||
if(m_pp.level2 == 0)
|
if(m_pp.level2 == 0)
|
||||||
m_pp.points += 5;
|
m_pp.points += 5;
|
||||||
else
|
else
|
||||||
@ -423,6 +427,18 @@ void Client::SetLevel(uint8 set_level, bool command)
|
|||||||
}
|
}
|
||||||
if(set_level > m_pp.level) {
|
if(set_level > m_pp.level) {
|
||||||
parse->EventPlayer(EVENT_LEVEL_UP, this, "", 0);
|
parse->EventPlayer(EVENT_LEVEL_UP, this, "", 0);
|
||||||
|
/* QS: PlayerLogLevels */
|
||||||
|
if (RuleB(QueryServ, PlayerLogLevels)){
|
||||||
|
std::string event_desc = StringFormat("Leveled UP :: to Level:%i from Level:%i in zoneid:%i instid:%i", set_level, m_pp.level, this->GetZoneID(), this->GetInstanceID());
|
||||||
|
QServ->PlayerLogEvent(Player_Log_Levels, this->CharacterID(), event_desc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (set_level < m_pp.level){
|
||||||
|
/* QS: PlayerLogLevels */
|
||||||
|
if (RuleB(QueryServ, PlayerLogLevels)){
|
||||||
|
std::string event_desc = StringFormat("Leveled DOWN :: to Level:%i from Level:%i in zoneid:%i instid:%i", set_level, m_pp.level, this->GetZoneID(), this->GetInstanceID());
|
||||||
|
QServ->PlayerLogEvent(Player_Log_Levels, this->CharacterID(), event_desc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_pp.level = set_level;
|
m_pp.level = set_level;
|
||||||
@ -432,34 +448,34 @@ void Client::SetLevel(uint8 set_level, bool command)
|
|||||||
lu->exp = 0;
|
lu->exp = 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
float tmpxp = (float) ( (float) m_pp.exp - GetEXPForLevel( GetLevel() )) /
|
float tmpxp = (float) ( (float) m_pp.exp - GetEXPForLevel( GetLevel() )) / ( (float) GetEXPForLevel(GetLevel()+1) - GetEXPForLevel(GetLevel()));
|
||||||
( (float) GetEXPForLevel(GetLevel()+1) - GetEXPForLevel(GetLevel()));
|
|
||||||
lu->exp = (uint32)(330.0f * tmpxp);
|
lu->exp = (uint32)(330.0f * tmpxp);
|
||||||
}
|
}
|
||||||
QueuePacket(outapp);
|
QueuePacket(outapp);
|
||||||
safe_delete(outapp);
|
safe_delete(outapp);
|
||||||
this->SendAppearancePacket(AT_WhoLevel, set_level); // who level change
|
this->SendAppearancePacket(AT_WhoLevel, set_level); // who level change
|
||||||
|
|
||||||
LogFile->write(EQEMuLog::Normal,"Setting Level for %s to %i", GetName(), set_level);
|
LogFile->write(EQEMuLog::Normal,"Setting Level for %s to %i", GetName(), set_level);
|
||||||
|
|
||||||
CalcBonuses();
|
CalcBonuses();
|
||||||
if(!RuleB(Character, HealOnLevel))
|
|
||||||
{
|
if(!RuleB(Character, HealOnLevel)) {
|
||||||
int mhp = CalcMaxHP();
|
int mhp = CalcMaxHP();
|
||||||
if(GetHP() > mhp)
|
if(GetHP() > mhp)
|
||||||
SetHP(mhp);
|
SetHP(mhp);
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
SetHP(CalcMaxHP()); // Why not, lets give them a free heal
|
SetHP(CalcMaxHP()); // Why not, lets give them a free heal
|
||||||
}
|
}
|
||||||
|
|
||||||
DoTributeUpdate();
|
DoTributeUpdate();
|
||||||
SendHPUpdate();
|
SendHPUpdate();
|
||||||
SetMana(CalcMaxMana());
|
SetMana(CalcMaxMana());
|
||||||
UpdateWho();
|
UpdateWho();
|
||||||
if(GetMerc())
|
|
||||||
UpdateMercLevel();
|
if(GetMerc())
|
||||||
|
UpdateMercLevel();
|
||||||
|
|
||||||
Save();
|
Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -508,23 +524,13 @@ uint32 Client::GetEXPForLevel(uint16 check_level)
|
|||||||
uint32 finalxp = uint32(base * mod);
|
uint32 finalxp = uint32(base * mod);
|
||||||
finalxp = mod_client_xp_for_level(finalxp, check_level);
|
finalxp = mod_client_xp_for_level(finalxp, check_level);
|
||||||
|
|
||||||
return(finalxp);
|
return finalxp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::AddLevelBasedExp(uint8 exp_percentage, uint8 max_level) {
|
void Client::AddLevelBasedExp(uint8 exp_percentage, uint8 max_level) {
|
||||||
|
if (exp_percentage > 100) { exp_percentage = 100; }
|
||||||
if (exp_percentage > 100)
|
if (!max_level || GetLevel() < max_level) { max_level = GetLevel(); }
|
||||||
{
|
uint32 newexp = GetEXP() + ((GetEXPForLevel(max_level + 1) - GetEXPForLevel(max_level)) * exp_percentage / 100);
|
||||||
exp_percentage = 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!max_level || GetLevel() < max_level)
|
|
||||||
{
|
|
||||||
max_level = GetLevel();
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32 newexp = GetEXP() + ((GetEXPForLevel(max_level + 1) - GetEXPForLevel(max_level)) * exp_percentage / 100);
|
|
||||||
|
|
||||||
SetEXP(newexp, GetAAXP());
|
SetEXP(newexp, GetAAXP());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -666,28 +672,25 @@ void Client::SendLeadershipEXPUpdate() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32 Client::GetCharMaxLevelFromQGlobal() {
|
uint32 Client::GetCharMaxLevelFromQGlobal() {
|
||||||
|
QGlobalCache *char_c = nullptr;
|
||||||
|
char_c = this->GetQGlobals();
|
||||||
|
|
||||||
QGlobalCache *char_c = nullptr;
|
std::list<QGlobal> globalMap;
|
||||||
char_c = this->GetQGlobals();
|
uint32 ntype = 0;
|
||||||
|
|
||||||
std::list<QGlobal> globalMap;
|
if(char_c) {
|
||||||
uint32 ntype = 0;
|
QGlobalCache::Combine(globalMap, char_c->GetBucket(), ntype, this->CharacterID(), zone->GetZoneID());
|
||||||
|
}
|
||||||
|
|
||||||
if(char_c)
|
std::list<QGlobal>::iterator iter = globalMap.begin();
|
||||||
{
|
uint32 gcount = 0;
|
||||||
QGlobalCache::Combine(globalMap, char_c->GetBucket(), ntype, this->CharacterID(), zone->GetZoneID());
|
while(iter != globalMap.end()) {
|
||||||
}
|
if((*iter).name.compare("CharMaxLevel") == 0){
|
||||||
|
return atoi((*iter).value.c_str());
|
||||||
|
}
|
||||||
|
++iter;
|
||||||
|
++gcount;
|
||||||
|
}
|
||||||
|
|
||||||
std::list<QGlobal>::iterator iter = globalMap.begin();
|
return false;
|
||||||
uint32 gcount = 0;
|
|
||||||
while(iter != globalMap.end())
|
|
||||||
{
|
|
||||||
if((*iter).name.compare("CharMaxLevel") == 0){
|
|
||||||
return atoi((*iter).value.c_str());
|
|
||||||
}
|
|
||||||
++iter;
|
|
||||||
++gcount;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false; // Default is false
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -193,11 +193,10 @@ void Group::SplitMoney(uint32 copper, uint32 silver, uint32 gold, uint32 platinu
|
|||||||
|
|
||||||
for (i = 0; i < MAX_GROUP_MEMBERS; i++) {
|
for (i = 0; i < MAX_GROUP_MEMBERS; i++) {
|
||||||
if (members[i] != nullptr && members[i]->IsClient()) { // If Group Member is Client
|
if (members[i] != nullptr && members[i]->IsClient()) { // If Group Member is Client
|
||||||
Client *c = members[i]->CastToClient();
|
Client *c = members[i]->CastToClient();
|
||||||
//I could not get MoneyOnCorpse to work, so we use this
|
//I could not get MoneyOnCorpse to work, so we use this
|
||||||
c->AddMoneyToPP(cpsplit, spsplit, gpsplit, ppsplit, true);
|
c->AddMoneyToPP(cpsplit, spsplit, gpsplit, ppsplit, true);
|
||||||
|
c->Message(2, msg.c_str());
|
||||||
c->Message(2, msg.c_str());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -311,7 +311,7 @@ Mob *HateList::GetTop(Mob *center)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cur->ent->Sanctuary()) {
|
if (cur->ent->Sanctuary()) {
|
||||||
if(hate == -1)
|
if(hate == -1)
|
||||||
{
|
{
|
||||||
top = cur->ent;
|
top = cur->ent;
|
||||||
|
|||||||
@ -1134,7 +1134,7 @@ void Lua_Client::Signal(uint32 id) {
|
|||||||
|
|
||||||
void Lua_Client::AddAlternateCurrencyValue(uint32 currency, int amount) {
|
void Lua_Client::AddAlternateCurrencyValue(uint32 currency, int amount) {
|
||||||
Lua_Safe_Call_Void();
|
Lua_Safe_Call_Void();
|
||||||
self->AddAlternateCurrencyValue(currency, amount);
|
self->AddAlternateCurrencyValue(currency, amount, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Lua_Client::SendWebLink(const char *site) {
|
void Lua_Client::SendWebLink(const char *site) {
|
||||||
|
|||||||
@ -183,6 +183,7 @@ Mob::Mob(const char* in_name,
|
|||||||
has_MGB = false;
|
has_MGB = false;
|
||||||
has_ProjectIllusion = false;
|
has_ProjectIllusion = false;
|
||||||
SpellPowerDistanceMod = 0;
|
SpellPowerDistanceMod = 0;
|
||||||
|
last_los_check = false;
|
||||||
|
|
||||||
if(in_aa_title>0)
|
if(in_aa_title>0)
|
||||||
aa_title = in_aa_title;
|
aa_title = in_aa_title;
|
||||||
@ -341,6 +342,7 @@ Mob::Mob(const char* in_name,
|
|||||||
viral_spells[i] = 0;
|
viral_spells[i] = 0;
|
||||||
}
|
}
|
||||||
pStandingPetOrder = SPO_Follow;
|
pStandingPetOrder = SPO_Follow;
|
||||||
|
pseudo_rooted = false;
|
||||||
|
|
||||||
see_invis = in_see_invis;
|
see_invis = in_see_invis;
|
||||||
see_invis_undead = in_see_invis_undead != 0;
|
see_invis_undead = in_see_invis_undead != 0;
|
||||||
|
|||||||
@ -464,6 +464,8 @@ public:
|
|||||||
bool CheckLosFN(float posX, float posY, float posZ, float mobSize);
|
bool CheckLosFN(float posX, float posY, float posZ, float mobSize);
|
||||||
inline void SetChanged() { pLastChange = Timer::GetCurrentTime(); }
|
inline void SetChanged() { pLastChange = Timer::GetCurrentTime(); }
|
||||||
inline const uint32 LastChange() const { return pLastChange; }
|
inline const uint32 LastChange() const { return pLastChange; }
|
||||||
|
inline void SetLastLosState(bool value) { last_los_check = value; }
|
||||||
|
inline bool CheckLastLosState() const { return last_los_check; }
|
||||||
|
|
||||||
//Quest
|
//Quest
|
||||||
void QuestReward(Client *c = nullptr, uint32 silver = 0, uint32 gold = 0, uint32 platinum = 0);
|
void QuestReward(Client *c = nullptr, uint32 silver = 0, uint32 gold = 0, uint32 platinum = 0);
|
||||||
@ -752,7 +754,8 @@ public:
|
|||||||
inline const bool IsRooted() const { return rooted || permarooted; }
|
inline const bool IsRooted() const { return rooted || permarooted; }
|
||||||
inline const bool HasVirus() const { return has_virus; }
|
inline const bool HasVirus() const { return has_virus; }
|
||||||
int GetSnaredAmount();
|
int GetSnaredAmount();
|
||||||
|
inline const bool IsPseudoRooted() const { return pseudo_rooted; }
|
||||||
|
inline void SetPseudoRoot(bool prState) { pseudo_rooted = prState; }
|
||||||
|
|
||||||
int GetCurWp() { return cur_wp; }
|
int GetCurWp() { return cur_wp; }
|
||||||
|
|
||||||
@ -1119,6 +1122,8 @@ protected:
|
|||||||
bool has_MGB;
|
bool has_MGB;
|
||||||
bool has_ProjectIllusion;
|
bool has_ProjectIllusion;
|
||||||
int16 SpellPowerDistanceMod;
|
int16 SpellPowerDistanceMod;
|
||||||
|
bool last_los_check;
|
||||||
|
bool pseudo_rooted;
|
||||||
|
|
||||||
// Bind wound
|
// Bind wound
|
||||||
Timer bindwound_timer;
|
Timer bindwound_timer;
|
||||||
|
|||||||
@ -48,6 +48,7 @@
|
|||||||
#include "worldserver.h"
|
#include "worldserver.h"
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
#include "zone.h"
|
#include "zone.h"
|
||||||
|
#include "queryserv.h"
|
||||||
#include "command.h"
|
#include "command.h"
|
||||||
#include "zone_config.h"
|
#include "zone_config.h"
|
||||||
#include "titles.h"
|
#include "titles.h"
|
||||||
@ -98,6 +99,7 @@ npcDecayTimes_Struct npcCorpseDecayTimes[100];
|
|||||||
TitleManager title_manager;
|
TitleManager title_manager;
|
||||||
DBAsyncFinishedQueue MTdbafq;
|
DBAsyncFinishedQueue MTdbafq;
|
||||||
DBAsync *dbasync = nullptr;
|
DBAsync *dbasync = nullptr;
|
||||||
|
QueryServ *QServ = 0;
|
||||||
TaskManager *taskmanager = 0;
|
TaskManager *taskmanager = 0;
|
||||||
QuestParserCollection *parse = 0;
|
QuestParserCollection *parse = 0;
|
||||||
|
|
||||||
@ -114,6 +116,8 @@ int main(int argc, char** argv) {
|
|||||||
|
|
||||||
const char *zone_name;
|
const char *zone_name;
|
||||||
|
|
||||||
|
QServ = new QueryServ;
|
||||||
|
|
||||||
if(argc == 3) {
|
if(argc == 3) {
|
||||||
worldserver.SetLauncherName(argv[2]);
|
worldserver.SetLauncherName(argv[2]);
|
||||||
worldserver.SetLaunchedName(argv[1]);
|
worldserver.SetLaunchedName(argv[1]);
|
||||||
@ -622,7 +626,7 @@ void LoadSpells(EQEmu::MemoryMappedFile **mmf) {
|
|||||||
SPDAT_RECORDS = records;
|
SPDAT_RECORDS = records;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Update Window Title with relevant information */
|
||||||
void UpdateWindowTitle(char* iNewTitle) {
|
void UpdateWindowTitle(char* iNewTitle) {
|
||||||
#ifdef _WINDOWS
|
#ifdef _WINDOWS
|
||||||
char tmp[500];
|
char tmp[500];
|
||||||
@ -634,7 +638,7 @@ void UpdateWindowTitle(char* iNewTitle) {
|
|||||||
#if defined(GOTFRAGS) || defined(_EQDEBUG)
|
#if defined(GOTFRAGS) || defined(_EQDEBUG)
|
||||||
snprintf(tmp, sizeof(tmp), "%i: %s, %i clients, %i", ZoneConfig::get()->ZonePort, zone->GetShortName(), numclients, getpid());
|
snprintf(tmp, sizeof(tmp), "%i: %s, %i clients, %i", ZoneConfig::get()->ZonePort, zone->GetShortName(), numclients, getpid());
|
||||||
#else
|
#else
|
||||||
snprintf(tmp, sizeof(tmp), "%i: %s, %i clients", ZoneConfig::get()->ZonePort, zone->GetShortName(), numclients);
|
snprintf(tmp, sizeof(tmp), "%s :: clients: %i inst_id: %i inst_ver: %i :: port: %i", zone->GetShortName(), numclients, zone->GetInstanceID(), zone->GetInstanceVersion(), ZoneConfig::get()->ZonePort);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
@ -1320,6 +1320,8 @@ XS(XS_Client_MovePCInstance)
|
|||||||
else
|
else
|
||||||
_log(CLIENT__ERROR, "Perl(XS_Client_MovePCInstance) attempted to process an Unknown type reference");
|
_log(CLIENT__ERROR, "Perl(XS_Client_MovePCInstance) attempted to process an Unknown type reference");
|
||||||
|
|
||||||
|
Perl_croak(aTHX_ "THIS is not of type Client");
|
||||||
|
|
||||||
Perl_croak(aTHX_ "THIS is not of type Client");
|
Perl_croak(aTHX_ "THIS is not of type Client");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -300,8 +300,6 @@ void ZoneDatabase::RefreshPetitionsFromDB()
|
|||||||
newpet->SetSentTime2(atol(row[13]));
|
newpet->SetSentTime2(atol(row[13]));
|
||||||
newpet->SetGMText(row[14]);
|
newpet->SetGMText(row[14]);
|
||||||
|
|
||||||
std::cout << "Petition " << row[0] << " pettime = " << newpet->GetSentTime() << std::endl;
|
|
||||||
|
|
||||||
if (atoi(row[12]) == 1)
|
if (atoi(row[12]) == 1)
|
||||||
newpet->SetCheckedOut(true);
|
newpet->SetCheckedOut(true);
|
||||||
else
|
else
|
||||||
|
|||||||
52
zone/queryserv.cpp
Normal file
52
zone/queryserv.cpp
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
/* EQEMu: Everquest Server Emulator
|
||||||
|
Copyright (C) 2001-2014 EQEMu Development Team (http://eqemulator.net)
|
||||||
|
|
||||||
|
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
|
||||||
|
the Free Software Foundation; version 2 of the License.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||||
|
are required to give you total support for your newly bought product;
|
||||||
|
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "../common/debug.h"
|
||||||
|
#include "../common/servertalk.h"
|
||||||
|
#include "../common/string_util.h"
|
||||||
|
#include "queryserv.h"
|
||||||
|
#include "worldserver.h"
|
||||||
|
#include "net.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
extern WorldServer worldserver;
|
||||||
|
extern QueryServ* QServ;
|
||||||
|
|
||||||
|
QueryServ::QueryServ(){
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryServ::~QueryServ(){
|
||||||
|
}
|
||||||
|
|
||||||
|
void QueryServ::SendQuery(std::string Query)
|
||||||
|
{
|
||||||
|
ServerPacket* pack = new ServerPacket(ServerOP_QSSendQuery, Query.length() + 5);
|
||||||
|
pack->WriteUInt32(Query.length()); /* Pack Query String Size so it can be dynamically broken out at queryserv */
|
||||||
|
pack->WriteString(Query.c_str()); /* Query */
|
||||||
|
worldserver.SendPacket(pack);
|
||||||
|
safe_delete(pack);
|
||||||
|
}
|
||||||
|
|
||||||
|
void QueryServ::PlayerLogEvent(int Event_Type, int Character_ID, std::string Event_Desc)
|
||||||
|
{
|
||||||
|
std::string query = StringFormat(
|
||||||
|
"INSERT INTO `qs_player_events` (event, char_id, event_desc, time) VALUES (%i, %i, '%s', UNIX_TIMESTAMP(now()))",
|
||||||
|
Event_Type, Character_ID, EscapeString(Event_Desc.c_str()).c_str());
|
||||||
|
SendQuery(query);
|
||||||
|
}
|
||||||
35
zone/queryserv.h
Normal file
35
zone/queryserv.h
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
#ifndef QUERYSERV_ZONE_H
|
||||||
|
#define QUERYSERV_ZONE_H
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
enum PlayerGenericLogEventTypes
|
||||||
|
These Enums are for the generic logging table that are not complex and require more advanced logic
|
||||||
|
*/
|
||||||
|
|
||||||
|
enum PlayerGenericLogEventTypes {
|
||||||
|
Player_Log_Quest = 1,
|
||||||
|
Player_Log_Zoning,
|
||||||
|
Player_Log_Deaths,
|
||||||
|
Player_Log_Connect_State,
|
||||||
|
Player_Log_Levels,
|
||||||
|
Player_Log_Keyring_Addition,
|
||||||
|
Player_Log_QGlobal_Update,
|
||||||
|
Player_Log_Task_Updates,
|
||||||
|
Player_Log_AA_Purchases,
|
||||||
|
Player_Log_Trade_Skill_Events,
|
||||||
|
Player_Log_Issued_Commands,
|
||||||
|
Player_Log_Money_Transactions,
|
||||||
|
Player_Log_Alternate_Currency_Transactions,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class QueryServ{
|
||||||
|
public:
|
||||||
|
QueryServ();
|
||||||
|
~QueryServ();
|
||||||
|
void SendQuery(std::string Query);
|
||||||
|
void PlayerLogEvent(int Event_Type, int Character_ID, std::string Event_Desc);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* QUERYSERV_ZONE_H */
|
||||||
@ -75,12 +75,12 @@ And then at then end of embparser.cpp, add:
|
|||||||
#include "../common/rulesys.h"
|
#include "../common/rulesys.h"
|
||||||
#include "qglobals.h"
|
#include "qglobals.h"
|
||||||
#include "quest_parser_collection.h"
|
#include "quest_parser_collection.h"
|
||||||
|
#include "queryserv.h"
|
||||||
#ifdef BOTS
|
#ifdef BOTS
|
||||||
#include "bot.h"
|
#include "bot.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
extern QueryServ* QServ;
|
||||||
extern Zone* zone;
|
extern Zone* zone;
|
||||||
extern WorldServer worldserver;
|
extern WorldServer worldserver;
|
||||||
extern EntityList entity_list;
|
extern EntityList entity_list;
|
||||||
@ -172,8 +172,7 @@ void QuestManager::EndQuest() {
|
|||||||
cur = QTimerList.erase(cur);
|
cur = QTimerList.erase(cur);
|
||||||
else
|
else
|
||||||
++cur;
|
++cur;
|
||||||
}
|
}
|
||||||
|
|
||||||
run.owner->Depop();
|
run.owner->Depop();
|
||||||
}
|
}
|
||||||
quests_running_.pop();
|
quests_running_.pop();
|
||||||
@ -1294,33 +1293,29 @@ void QuestManager::setglobal(const char *varname, const char *newvalue, int opti
|
|||||||
int qgNpcid = owner->GetNPCTypeID();
|
int qgNpcid = owner->GetNPCTypeID();
|
||||||
|
|
||||||
/* options value determines the availability of global variables to NPCs when a quest begins
|
/* options value determines the availability of global variables to NPCs when a quest begins
|
||||||
------------------------------------------------------------------
|
------------------------------------------------------------------
|
||||||
value npcid player zone
|
value npcid player zone
|
||||||
------------------------------------------------------------------
|
------------------------------------------------------------------
|
||||||
0 this this this
|
0 this this this
|
||||||
1 all this this
|
1 all this this
|
||||||
2 this all this
|
2 this all this
|
||||||
3 all all this
|
3 all all this
|
||||||
4 this this all
|
4 this this all
|
||||||
5 all this all
|
5 all this all
|
||||||
6 this all all
|
6 this all all
|
||||||
7 all all all
|
7 all all all
|
||||||
*/
|
*/
|
||||||
if (initiator && initiator->IsClient()) // some events like waypoint and spawn don't have a player involved
|
|
||||||
{
|
|
||||||
qgCharid=initiator->CharacterID();
|
|
||||||
}
|
|
||||||
|
|
||||||
else
|
if (initiator && initiator->IsClient()){ // some events like waypoint and spawn don't have a player involved
|
||||||
{
|
qgCharid=initiator->CharacterID();
|
||||||
|
}
|
||||||
|
else {
|
||||||
qgCharid=-qgNpcid; // make char id negative npc id as a fudge
|
qgCharid=-qgNpcid; // make char id negative npc id as a fudge
|
||||||
}
|
}
|
||||||
if (options < 0 || options > 7)
|
if (options < 0 || options > 7) {
|
||||||
{
|
|
||||||
std::cerr << "Invalid options for global var " << varname << " using defaults" << std::endl;
|
std::cerr << "Invalid options for global var " << varname << " using defaults" << std::endl;
|
||||||
} // default = 0 (only this npcid,player and zone)
|
} // default = 0 (only this npcid,player and zone)
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
if (options & 1)
|
if (options & 1)
|
||||||
qgNpcid=0;
|
qgNpcid=0;
|
||||||
if (options & 2)
|
if (options & 2)
|
||||||
@ -1330,30 +1325,32 @@ void QuestManager::setglobal(const char *varname, const char *newvalue, int opti
|
|||||||
}
|
}
|
||||||
|
|
||||||
InsertQuestGlobal(qgCharid, qgNpcid, qgZoneid, varname, newvalue, QGVarDuration(duration));
|
InsertQuestGlobal(qgCharid, qgNpcid, qgZoneid, varname, newvalue, QGVarDuration(duration));
|
||||||
|
|
||||||
|
/* QS: PlayerLogQGlobalUpdate */
|
||||||
|
if (RuleB(QueryServ, PlayerLogQGlobalUpdate) && qgCharid && qgCharid > 0 && initiator && initiator->IsClient()){
|
||||||
|
std::string event_desc = StringFormat("Update :: qglobal:%s to qvalue:%s zoneid:%i instid:%i", varname, newvalue, initiator->GetZoneID(), initiator->GetInstanceID());
|
||||||
|
QServ->PlayerLogEvent(Player_Log_QGlobal_Update, qgCharid, event_desc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Inserts global variable into quest_globals table */
|
/* Inserts global variable into quest_globals table */
|
||||||
int QuestManager::InsertQuestGlobal(
|
int QuestManager::InsertQuestGlobal(int charid, int npcid, int zoneid, const char *varname, const char *varvalue, int duration) {
|
||||||
int charid, int npcid, int zoneid,
|
|
||||||
const char *varname, const char *varvalue,
|
|
||||||
int duration)
|
|
||||||
{
|
|
||||||
char *query = 0;
|
char *query = 0;
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||||
|
|
||||||
// Make duration string either "unix_timestamp(now()) + xxx" or "NULL"
|
// Make duration string either "unix_timestamp(now()) + xxx" or "NULL"
|
||||||
std::stringstream duration_ss;
|
std::stringstream duration_ss;
|
||||||
if (duration == INT_MAX)
|
if (duration == INT_MAX) {
|
||||||
{
|
|
||||||
duration_ss << "NULL";
|
duration_ss << "NULL";
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
duration_ss << "unix_timestamp(now()) + " << duration;
|
duration_ss << "unix_timestamp(now()) + " << duration;
|
||||||
}
|
}
|
||||||
|
|
||||||
//NOTE: this should be escaping the contents of arglist
|
/*
|
||||||
//npcwise a malicious script can arbitrarily alter the DB
|
NOTE: this should be escaping the contents of arglist
|
||||||
|
npcwise a malicious script can arbitrarily alter the DB
|
||||||
|
*/
|
||||||
uint32 last_id = 0;
|
uint32 last_id = 0;
|
||||||
if (!database.RunQuery(query, MakeAnyLenString(&query,
|
if (!database.RunQuery(query, MakeAnyLenString(&query,
|
||||||
"REPLACE INTO quest_globals (charid, npcid, zoneid, name, value, expdate)"
|
"REPLACE INTO quest_globals (charid, npcid, zoneid, name, value, expdate)"
|
||||||
@ -1365,9 +1362,8 @@ int QuestManager::InsertQuestGlobal(
|
|||||||
}
|
}
|
||||||
safe_delete_array(query);
|
safe_delete_array(query);
|
||||||
|
|
||||||
if(zone)
|
if(zone) {
|
||||||
{
|
/* Delete existing qglobal data and update zone processes */
|
||||||
//first delete our global
|
|
||||||
ServerPacket* pack = new ServerPacket(ServerOP_QGlobalDelete, sizeof(ServerQGlobalDelete_Struct));
|
ServerPacket* pack = new ServerPacket(ServerOP_QGlobalDelete, sizeof(ServerQGlobalDelete_Struct));
|
||||||
ServerQGlobalDelete_Struct *qgd = (ServerQGlobalDelete_Struct*)pack->pBuffer;
|
ServerQGlobalDelete_Struct *qgd = (ServerQGlobalDelete_Struct*)pack->pBuffer;
|
||||||
qgd->npc_id = npcid;
|
qgd->npc_id = npcid;
|
||||||
@ -1383,18 +1379,16 @@ int QuestManager::InsertQuestGlobal(
|
|||||||
worldserver.SendPacket(pack);
|
worldserver.SendPacket(pack);
|
||||||
safe_delete(pack);
|
safe_delete(pack);
|
||||||
|
|
||||||
//then create a new one with the new id
|
/* Create new qglobal data and update zone processes */
|
||||||
pack = new ServerPacket(ServerOP_QGlobalUpdate, sizeof(ServerQGlobalUpdate_Struct));
|
pack = new ServerPacket(ServerOP_QGlobalUpdate, sizeof(ServerQGlobalUpdate_Struct));
|
||||||
ServerQGlobalUpdate_Struct *qgu = (ServerQGlobalUpdate_Struct*)pack->pBuffer;
|
ServerQGlobalUpdate_Struct *qgu = (ServerQGlobalUpdate_Struct*)pack->pBuffer;
|
||||||
qgu->npc_id = npcid;
|
qgu->npc_id = npcid;
|
||||||
qgu->char_id = charid;
|
qgu->char_id = charid;
|
||||||
qgu->zone_id = zoneid;
|
qgu->zone_id = zoneid;
|
||||||
if(duration == INT_MAX)
|
if(duration == INT_MAX) {
|
||||||
{
|
|
||||||
qgu->expdate = 0xFFFFFFFF;
|
qgu->expdate = 0xFFFFFFFF;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
qgu->expdate = Timer::GetTimeSeconds() + duration;
|
qgu->expdate = Timer::GetTimeSeconds() + duration;
|
||||||
}
|
}
|
||||||
strcpy((char*)qgu->name, varname);
|
strcpy((char*)qgu->name, varname);
|
||||||
@ -1420,8 +1414,7 @@ int QuestManager::InsertQuestGlobal(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QuestManager::targlobal(const char *varname, const char *value, const char *duration, int qgNpcid, int qgCharid, int qgZoneid)
|
void QuestManager::targlobal(const char *varname, const char *value, const char *duration, int qgNpcid, int qgCharid, int qgZoneid) {
|
||||||
{
|
|
||||||
InsertQuestGlobal(qgCharid, qgNpcid, qgZoneid, varname, value, QGVarDuration(duration));
|
InsertQuestGlobal(qgCharid, qgNpcid, qgZoneid, varname, value, QGVarDuration(duration));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1432,15 +1425,24 @@ void QuestManager::delglobal(const char *varname) {
|
|||||||
int qgZoneid=zone->GetZoneID();
|
int qgZoneid=zone->GetZoneID();
|
||||||
int qgCharid=0;
|
int qgCharid=0;
|
||||||
int qgNpcid=owner->GetNPCTypeID();
|
int qgNpcid=owner->GetNPCTypeID();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (initiator && initiator->IsClient()) // some events like waypoint and spawn don't have a player involved
|
if (initiator && initiator->IsClient()) // some events like waypoint and spawn don't have a player involved
|
||||||
{
|
{
|
||||||
qgCharid=initiator->CharacterID();
|
qgCharid=initiator->CharacterID();
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
qgCharid=-qgNpcid; // make char id negative npc id as a fudge
|
qgCharid=-qgNpcid; // make char id negative npc id as a fudge
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* QS: PlayerLogQGlobalUpdate */
|
||||||
|
if (RuleB(QueryServ, PlayerLogQGlobalUpdate) && qgCharid && qgCharid > 0 && initiator && initiator->IsClient()){
|
||||||
|
std::string event_desc = StringFormat("Deleted :: qglobal:%s zoneid:%i instid:%i", varname, initiator->GetZoneID(), initiator->GetInstanceID());
|
||||||
|
QServ->PlayerLogEvent(Player_Log_QGlobal_Update, qgCharid, event_desc);
|
||||||
|
}
|
||||||
|
|
||||||
if (!database.RunQuery(query,
|
if (!database.RunQuery(query,
|
||||||
MakeAnyLenString(&query,
|
MakeAnyLenString(&query,
|
||||||
"DELETE FROM quest_globals WHERE name='%s'"
|
"DELETE FROM quest_globals WHERE name='%s'"
|
||||||
@ -1451,8 +1453,7 @@ void QuestManager::delglobal(const char *varname) {
|
|||||||
}
|
}
|
||||||
safe_delete_array(query);
|
safe_delete_array(query);
|
||||||
|
|
||||||
if(zone)
|
if(zone) {
|
||||||
{
|
|
||||||
ServerPacket* pack = new ServerPacket(ServerOP_QGlobalDelete, sizeof(ServerQGlobalDelete_Struct));
|
ServerPacket* pack = new ServerPacket(ServerOP_QGlobalDelete, sizeof(ServerQGlobalDelete_Struct));
|
||||||
ServerQGlobalDelete_Struct *qgu = (ServerQGlobalDelete_Struct*)pack->pBuffer;
|
ServerQGlobalDelete_Struct *qgu = (ServerQGlobalDelete_Struct*)pack->pBuffer;
|
||||||
|
|
||||||
@ -1701,17 +1702,14 @@ void QuestManager::showgrid(int grid) {
|
|||||||
pts.push_back(pt);
|
pts.push_back(pt);
|
||||||
|
|
||||||
// Retrieve all waypoints for this grid
|
// Retrieve all waypoints for this grid
|
||||||
if(database.RunQuery(query,MakeAnyLenString(&query,"SELECT `x`,`y`,`z` FROM grid_entries WHERE `gridid`=%i AND `zoneid`=%i ORDER BY `number`",grid,zone->GetZoneID()),errbuf,&result))
|
if(database.RunQuery(query,MakeAnyLenString(&query,"SELECT `x`,`y`,`z` FROM grid_entries WHERE `gridid`=%i AND `zoneid`=%i ORDER BY `number`",grid,zone->GetZoneID()),errbuf,&result)) {
|
||||||
{
|
while((row = mysql_fetch_row(result))) {
|
||||||
while((row = mysql_fetch_row(result)))
|
|
||||||
{
|
|
||||||
pt.x = atof(row[0]);
|
pt.x = atof(row[0]);
|
||||||
pt.y = atof(row[1]);
|
pt.y = atof(row[1]);
|
||||||
pt.z = atof(row[2]);
|
pt.z = atof(row[2]);
|
||||||
pts.push_back(pt);
|
pts.push_back(pt);
|
||||||
}
|
}
|
||||||
mysql_free_result(result);
|
mysql_free_result(result);
|
||||||
|
|
||||||
initiator->SendPathPacket(pts);
|
initiator->SendPathPacket(pts);
|
||||||
}
|
}
|
||||||
else // DB query error!
|
else // DB query error!
|
||||||
|
|||||||
@ -28,8 +28,7 @@
|
|||||||
|
|
||||||
extern EntityList entity_list;
|
extern EntityList entity_list;
|
||||||
|
|
||||||
SpawnEntry::SpawnEntry( uint32 in_NPCType, int in_chance, uint8 in_npc_spawn_limit )
|
SpawnEntry::SpawnEntry( uint32 in_NPCType, int in_chance, uint8 in_npc_spawn_limit ) {
|
||||||
{
|
|
||||||
NPCType = in_NPCType;
|
NPCType = in_NPCType;
|
||||||
chance = in_chance;
|
chance = in_chance;
|
||||||
npc_spawn_limit = in_npc_spawn_limit;
|
npc_spawn_limit = in_npc_spawn_limit;
|
||||||
@ -57,7 +56,6 @@ uint32 SpawnGroup::GetNPCType() {
|
|||||||
int npcType = 0;
|
int npcType = 0;
|
||||||
int totalchance = 0;
|
int totalchance = 0;
|
||||||
|
|
||||||
//check limits on this spawn group and npc type
|
|
||||||
if(!entity_list.LimitCheckGroup(id, group_spawn_limit))
|
if(!entity_list.LimitCheckGroup(id, group_spawn_limit))
|
||||||
return(0);
|
return(0);
|
||||||
|
|
||||||
@ -68,7 +66,6 @@ uint32 SpawnGroup::GetNPCType() {
|
|||||||
for(; cur != end; ++cur) {
|
for(; cur != end; ++cur) {
|
||||||
SpawnEntry *se = *cur;
|
SpawnEntry *se = *cur;
|
||||||
|
|
||||||
//check limits on this spawn group and npc type
|
|
||||||
if(!entity_list.LimitCheckType(se->NPCType, se->npc_spawn_limit))
|
if(!entity_list.LimitCheckType(se->NPCType, se->npc_spawn_limit))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -93,7 +90,6 @@ uint32 SpawnGroup::GetNPCType() {
|
|||||||
roll -= se->chance;
|
roll -= se->chance;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//CODER implement random table
|
|
||||||
return npcType;
|
return npcType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,7 +145,6 @@ bool ZoneDatabase::LoadSpawnGroups(const char* zone_name, uint16 version, SpawnG
|
|||||||
MYSQL_RES *result;
|
MYSQL_RES *result;
|
||||||
MYSQL_ROW row;
|
MYSQL_ROW row;
|
||||||
|
|
||||||
// CODER new spawn code
|
|
||||||
query = 0;
|
query = 0;
|
||||||
if (RunQuery(query, MakeAnyLenString(&query, "SELECT DISTINCT(spawngroupID), spawngroup.name, spawngroup.spawn_limit, spawngroup.dist, spawngroup.max_x, spawngroup.min_x, spawngroup.max_y, spawngroup.min_y, spawngroup.delay, spawngroup.despawn, spawngroup.despawn_timer, spawngroup.mindelay FROM spawn2,spawngroup WHERE spawn2.spawngroupID=spawngroup.ID and spawn2.version=%u and zone='%s'", version, zone_name), errbuf, &result))
|
if (RunQuery(query, MakeAnyLenString(&query, "SELECT DISTINCT(spawngroupID), spawngroup.name, spawngroup.spawn_limit, spawngroup.dist, spawngroup.max_x, spawngroup.min_x, spawngroup.max_y, spawngroup.min_y, spawngroup.delay, spawngroup.despawn, spawngroup.despawn_timer, spawngroup.mindelay FROM spawn2,spawngroup WHERE spawn2.spawngroupID=spawngroup.ID and spawn2.version=%u and zone='%s'", version, zone_name), errbuf, &result))
|
||||||
{
|
{
|
||||||
@ -162,7 +157,7 @@ bool ZoneDatabase::LoadSpawnGroups(const char* zone_name, uint16 version, SpawnG
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::cerr << "Error2 in PopulateZoneLists query '" << query << "' " << errbuf << std::endl;
|
_log(ZONE__SPAWNS, "Error2 in PopulateZoneLists query '%s' ", query);
|
||||||
safe_delete_array(query);
|
safe_delete_array(query);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -182,18 +177,17 @@ bool ZoneDatabase::LoadSpawnGroups(const char* zone_name, uint16 version, SpawnG
|
|||||||
if (sg)
|
if (sg)
|
||||||
sg->AddSpawnEntry(newSpawnEntry);
|
sg->AddSpawnEntry(newSpawnEntry);
|
||||||
else
|
else
|
||||||
std::cout << "Error in SpawngroupID: " << row[0] << std::endl;
|
_log(ZONE__SPAWNS, "Error in LoadSpawnGroups %s ", query);
|
||||||
}
|
}
|
||||||
mysql_free_result(result);
|
mysql_free_result(result);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::cerr << "Error3 in PopulateZoneLists query '" << query << "' " << errbuf << std::endl;
|
_log(ZONE__SPAWNS, "Error2 in PopulateZoneLists query '%'", query);
|
||||||
safe_delete_array(query);
|
safe_delete_array(query);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// CODER end new spawn code
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -203,8 +197,6 @@ bool ZoneDatabase::LoadSpawnGroupsByID(int spawngroupid, SpawnGroupList* spawn_g
|
|||||||
MYSQL_RES *result;
|
MYSQL_RES *result;
|
||||||
MYSQL_ROW row;
|
MYSQL_ROW row;
|
||||||
|
|
||||||
|
|
||||||
// CODER new spawn code
|
|
||||||
query = 0;
|
query = 0;
|
||||||
if (RunQuery(query, MakeAnyLenString(&query, "SELECT DISTINCT spawngroup.id, spawngroup.name, spawngroup.spawn_limit, spawngroup.dist, spawngroup.max_x, spawngroup.min_x, spawngroup.max_y, spawngroup.min_y, spawngroup.delay, spawngroup.despawn, spawngroup.despawn_timer, spawngroup.mindelay FROM spawngroup WHERE spawngroup.ID='%i'", spawngroupid), errbuf, &result))
|
if (RunQuery(query, MakeAnyLenString(&query, "SELECT DISTINCT spawngroup.id, spawngroup.name, spawngroup.spawn_limit, spawngroup.dist, spawngroup.max_x, spawngroup.min_x, spawngroup.max_y, spawngroup.min_y, spawngroup.delay, spawngroup.despawn, spawngroup.despawn_timer, spawngroup.mindelay FROM spawngroup WHERE spawngroup.ID='%i'", spawngroupid), errbuf, &result))
|
||||||
{
|
{
|
||||||
@ -217,7 +209,7 @@ bool ZoneDatabase::LoadSpawnGroupsByID(int spawngroupid, SpawnGroupList* spawn_g
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::cerr << "Error2 in PopulateZoneLists query '" << query << "' " << errbuf << std::endl;
|
_log(ZONE__SPAWNS, "Error2 in PopulateZoneLists query %s", query);
|
||||||
safe_delete_array(query);
|
safe_delete_array(query);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -233,17 +225,16 @@ bool ZoneDatabase::LoadSpawnGroupsByID(int spawngroupid, SpawnGroupList* spawn_g
|
|||||||
if (sg)
|
if (sg)
|
||||||
sg->AddSpawnEntry(newSpawnEntry);
|
sg->AddSpawnEntry(newSpawnEntry);
|
||||||
else
|
else
|
||||||
std::cout << "Error in SpawngroupID: " << row[0] << std::endl;
|
_log(ZONE__SPAWNS, "Error in SpawngroupID: %s ", row[0]);
|
||||||
}
|
}
|
||||||
mysql_free_result(result);
|
mysql_free_result(result);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::cerr << "Error3 in PopulateZoneLists query '" << query << "' " << errbuf << std::endl;
|
_log(ZONE__SPAWNS, "Error3 in PopulateZoneLists query '%s'", row[0]);
|
||||||
safe_delete_array(query);
|
safe_delete_array(query);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// CODER end new spawn code
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -28,8 +28,6 @@
|
|||||||
#include "../common/rulesys.h"
|
#include "../common/rulesys.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int Mob::GetKickDamage() {
|
int Mob::GetKickDamage() {
|
||||||
int multiple=(GetLevel()*100/5);
|
int multiple=(GetLevel()*100/5);
|
||||||
multiple += 100;
|
multiple += 100;
|
||||||
@ -64,11 +62,9 @@ int Mob::GetBashDamage() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Mob::ApplySpecialAttackMod(SkillUseTypes skill, int32 &dmg, int32 &mindmg) {
|
void Mob::ApplySpecialAttackMod(SkillUseTypes skill, int32 &dmg, int32 &mindmg) {
|
||||||
|
|
||||||
int item_slot = -1;
|
int item_slot = -1;
|
||||||
//1: Apply bonus from AC (BOOT/SHIELD/HANDS) est. 40AC=6dmg
|
//1: Apply bonus from AC (BOOT/SHIELD/HANDS) est. 40AC=6dmg
|
||||||
if (IsClient()){
|
if (IsClient()){
|
||||||
|
|
||||||
switch (skill){
|
switch (skill){
|
||||||
|
|
||||||
case SkillFlyingKick:
|
case SkillFlyingKick:
|
||||||
@ -112,10 +108,8 @@ void Mob::DoSpecialAttackDamage(Mob *who, SkillUseTypes skill, int32 max_damage,
|
|||||||
if(hate_override > -1)
|
if(hate_override > -1)
|
||||||
hate = hate_override;
|
hate = hate_override;
|
||||||
|
|
||||||
if(skill == SkillBash)
|
if(skill == SkillBash){
|
||||||
{
|
if(IsClient()){
|
||||||
if(IsClient())
|
|
||||||
{
|
|
||||||
ItemInst *item = CastToClient()->GetInv().GetItem(MainSecondary);
|
ItemInst *item = CastToClient()->GetInv().GetItem(MainSecondary);
|
||||||
if(item)
|
if(item)
|
||||||
{
|
{
|
||||||
@ -186,6 +180,10 @@ void Client::OPCombatAbility(const EQApplicationPacket *app) {
|
|||||||
|
|
||||||
CombatAbility_Struct* ca_atk = (CombatAbility_Struct*) app->pBuffer;
|
CombatAbility_Struct* ca_atk = (CombatAbility_Struct*) app->pBuffer;
|
||||||
|
|
||||||
|
/* Check to see if actually have skill */
|
||||||
|
if (!MaxSkill(static_cast<SkillUseTypes>(ca_atk->m_skill)))
|
||||||
|
return;
|
||||||
|
|
||||||
if(GetTarget()->GetID() != ca_atk->m_target)
|
if(GetTarget()->GetID() != ca_atk->m_target)
|
||||||
return; //invalid packet.
|
return; //invalid packet.
|
||||||
|
|
||||||
@ -274,8 +272,7 @@ void Client::OPCombatAbility(const EQApplicationPacket *app) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ca_atk->m_atk == 100) && (ca_atk->m_skill == SkillFrenzy))
|
if ((ca_atk->m_atk == 100) && (ca_atk->m_skill == SkillFrenzy)){
|
||||||
{
|
|
||||||
CheckIncreaseSkill(SkillFrenzy, GetTarget(), 10);
|
CheckIncreaseSkill(SkillFrenzy, GetTarget(), 10);
|
||||||
int AtkRounds = 3;
|
int AtkRounds = 3;
|
||||||
int skillmod = 100*GetSkill(SkillFrenzy)/MaxSkill(SkillFrenzy);
|
int skillmod = 100*GetSkill(SkillFrenzy)/MaxSkill(SkillFrenzy);
|
||||||
@ -311,8 +308,7 @@ void Client::OPCombatAbility(const EQApplicationPacket *app) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(GetClass())
|
switch(GetClass()){
|
||||||
{
|
|
||||||
case BERSERKER:
|
case BERSERKER:
|
||||||
case WARRIOR:
|
case WARRIOR:
|
||||||
case RANGER:
|
case RANGER:
|
||||||
@ -384,8 +380,7 @@ void Client::OPCombatAbility(const EQApplicationPacket *app) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ReuseTime = (ReuseTime*HasteMod)/100;
|
ReuseTime = (ReuseTime*HasteMod)/100;
|
||||||
if(ReuseTime > 0)
|
if(ReuseTime > 0){
|
||||||
{
|
|
||||||
p_timers.Start(pTimerCombatAbility, ReuseTime);
|
p_timers.Start(pTimerCombatAbility, ReuseTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -403,8 +398,7 @@ int Mob::MonkSpecialAttack(Mob* other, uint8 unchecked_type)
|
|||||||
SkillUseTypes skill_type; //to avoid casting... even though it "would work"
|
SkillUseTypes skill_type; //to avoid casting... even though it "would work"
|
||||||
uint8 itemslot = MainFeet;
|
uint8 itemslot = MainFeet;
|
||||||
|
|
||||||
switch(unchecked_type)
|
switch(unchecked_type){
|
||||||
{
|
|
||||||
case SkillFlyingKick:{
|
case SkillFlyingKick:{
|
||||||
skill_type = SkillFlyingKick;
|
skill_type = SkillFlyingKick;
|
||||||
max_dmg = ((GetSTR()+GetSkill(skill_type)) * RuleI(Combat, FlyingKickBonus) / 100) + 35;
|
max_dmg = ((GetSTR()+GetSkill(skill_type)) * RuleI(Combat, FlyingKickBonus) / 100) + 35;
|
||||||
@ -484,8 +478,7 @@ int Mob::MonkSpecialAttack(Mob* other, uint8 unchecked_type)
|
|||||||
else
|
else
|
||||||
ht = ndamage = MakeRandomInt(min_dmg, max_dmg);
|
ht = ndamage = MakeRandomInt(min_dmg, max_dmg);
|
||||||
}
|
}
|
||||||
else
|
else{
|
||||||
{
|
|
||||||
ht = max_dmg;
|
ht = max_dmg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -535,7 +528,6 @@ void Mob::TryBackstab(Mob *other, int ReuseTime) {
|
|||||||
|
|
||||||
RogueBackstab(other,false,ReuseTime);
|
RogueBackstab(other,false,ReuseTime);
|
||||||
if (level > 54) {
|
if (level > 54) {
|
||||||
|
|
||||||
if(IsClient() && CastToClient()->CheckDoubleAttack(false))
|
if(IsClient() && CastToClient()->CheckDoubleAttack(false))
|
||||||
{
|
{
|
||||||
if(other->GetHP() > 0)
|
if(other->GetHP() > 0)
|
||||||
@ -619,12 +611,10 @@ void Mob::RogueBackstab(Mob* other, bool min_damage, int ReuseTime)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// determine minimum hits
|
// determine minimum hits
|
||||||
if (level < 51)
|
if (level < 51) {
|
||||||
{
|
|
||||||
min_hit = (level*15/10);
|
min_hit = (level*15/10);
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
// Trumpcard: Replaced switch statement with formula calc. This will give minhit increases all the way to 65.
|
// Trumpcard: Replaced switch statement with formula calc. This will give minhit increases all the way to 65.
|
||||||
min_hit = (level * ( level*5 - 105)) / 100;
|
min_hit = (level * ( level*5 - 105)) / 100;
|
||||||
}
|
}
|
||||||
@ -636,8 +626,7 @@ void Mob::RogueBackstab(Mob* other, bool min_damage, int ReuseTime)
|
|||||||
if(min_damage){
|
if(min_damage){
|
||||||
ndamage = min_hit;
|
ndamage = min_hit;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
if (max_hit < min_hit)
|
if (max_hit < min_hit)
|
||||||
max_hit = min_hit;
|
max_hit = min_hit;
|
||||||
|
|
||||||
@ -645,7 +634,6 @@ void Mob::RogueBackstab(Mob* other, bool min_damage, int ReuseTime)
|
|||||||
ndamage = max_hit;
|
ndamage = max_hit;
|
||||||
else
|
else
|
||||||
ndamage = MakeRandomInt(min_hit, max_hit);
|
ndamage = MakeRandomInt(min_hit, max_hit);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -792,28 +780,24 @@ void Client::RangedAttack(Mob* other, bool CanDoubleAttack) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
SendItemAnimation(GetTarget(), AmmoItem, SkillArchery);
|
SendItemAnimation(GetTarget(), AmmoItem, SkillArchery);
|
||||||
|
|
||||||
DoArcheryAttackDmg(GetTarget(), RangeWeapon, Ammo);
|
DoArcheryAttackDmg(GetTarget(), RangeWeapon, Ammo);
|
||||||
|
|
||||||
//EndlessQuiver AA base1 = 100% Chance to avoid consumption arrow.
|
//EndlessQuiver AA base1 = 100% Chance to avoid consumption arrow.
|
||||||
int ChanceAvoidConsume = aabonuses.ConsumeProjectile + itembonuses.ConsumeProjectile + spellbonuses.ConsumeProjectile;
|
int ChanceAvoidConsume = aabonuses.ConsumeProjectile + itembonuses.ConsumeProjectile + spellbonuses.ConsumeProjectile;
|
||||||
|
|
||||||
if (!ChanceAvoidConsume || (ChanceAvoidConsume < 100 && MakeRandomInt(0,99) > ChanceAvoidConsume)){
|
if (!ChanceAvoidConsume || (ChanceAvoidConsume < 100 && MakeRandomInt(0,99) > ChanceAvoidConsume)){
|
||||||
|
|
||||||
DeleteItemInInventory(ammo_slot, 1, true);
|
DeleteItemInInventory(ammo_slot, 1, true);
|
||||||
mlog(COMBAT__RANGED, "Consumed one arrow from slot %d", ammo_slot);
|
mlog(COMBAT__RANGED, "Consumed one arrow from slot %d", ammo_slot);
|
||||||
} else {
|
} else {
|
||||||
mlog(COMBAT__RANGED, "Endless Quiver prevented ammo consumption.");
|
mlog(COMBAT__RANGED, "Endless Quiver prevented ammo consumption.");
|
||||||
}
|
}
|
||||||
|
|
||||||
CheckIncreaseSkill(SkillArchery, GetTarget(), -15);
|
CheckIncreaseSkill(SkillArchery, GetTarget(), -15);
|
||||||
|
|
||||||
CommonBreakInvisible();
|
CommonBreakInvisible();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mob::DoArcheryAttackDmg(Mob* other, const ItemInst* RangeWeapon, const ItemInst* Ammo, uint16 weapon_damage, int16 chance_mod, int16 focus, int ReuseTime)
|
void Mob::DoArcheryAttackDmg(Mob* other, const ItemInst* RangeWeapon, const ItemInst* Ammo, uint16 weapon_damage, int16 chance_mod, int16 focus, int ReuseTime) {
|
||||||
{
|
|
||||||
if (!CanDoSpecialAttack(other))
|
if (!CanDoSpecialAttack(other))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -842,8 +826,7 @@ void Mob::DoArcheryAttackDmg(Mob* other, const ItemInst* RangeWeapon, const Item
|
|||||||
if (focus) //From FcBaseEffects
|
if (focus) //From FcBaseEffects
|
||||||
WDmg += WDmg*focus/100;
|
WDmg += WDmg*focus/100;
|
||||||
|
|
||||||
if((WDmg > 0) || (ADmg > 0))
|
if((WDmg > 0) || (ADmg > 0)) {
|
||||||
{
|
|
||||||
if(WDmg < 0)
|
if(WDmg < 0)
|
||||||
WDmg = 0;
|
WDmg = 0;
|
||||||
if(ADmg < 0)
|
if(ADmg < 0)
|
||||||
@ -944,8 +927,7 @@ void Mob::DoArcheryAttackDmg(Mob* other, const ItemInst* RangeWeapon, const Item
|
|||||||
}
|
}
|
||||||
|
|
||||||
//try proc on hits and misses
|
//try proc on hits and misses
|
||||||
if((RangeWeapon != nullptr) && GetTarget() && other && !other->HasDied())
|
if((RangeWeapon != nullptr) && GetTarget() && other && !other->HasDied()){
|
||||||
{
|
|
||||||
TryWeaponProc(RangeWeapon, other, MainRange);
|
TryWeaponProc(RangeWeapon, other, MainRange);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -965,14 +947,19 @@ void Mob::DoArcheryAttackDmg(Mob* other, const ItemInst* RangeWeapon, const Item
|
|||||||
|
|
||||||
void NPC::RangedAttack(Mob* other)
|
void NPC::RangedAttack(Mob* other)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
if (!other)
|
||||||
|
return;
|
||||||
//make sure the attack and ranged timers are up
|
//make sure the attack and ranged timers are up
|
||||||
//if the ranged timer is disabled, then they have no ranged weapon and shouldent be attacking anyhow
|
//if the ranged timer is disabled, then they have no ranged weapon and shouldent be attacking anyhow
|
||||||
if((attack_timer.Enabled() && !attack_timer.Check(false)) || (ranged_timer.Enabled() && !ranged_timer.Check()))
|
if((attack_timer.Enabled() && !attack_timer.Check(false)) || (ranged_timer.Enabled() && !ranged_timer.Check())){
|
||||||
{
|
|
||||||
mlog(COMBAT__RANGED, "Archery canceled. Timer not up. Attack %d, ranged %d", attack_timer.GetRemainingTime(), ranged_timer.GetRemainingTime());
|
mlog(COMBAT__RANGED, "Archery canceled. Timer not up. Attack %d, ranged %d", attack_timer.GetRemainingTime(), ranged_timer.GetRemainingTime());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!CheckLosFN(other))
|
||||||
|
return;
|
||||||
|
|
||||||
int attacks = GetSpecialAbilityParam(SPECATK_RANGED_ATK, 0);
|
int attacks = GetSpecialAbilityParam(SPECATK_RANGED_ATK, 0);
|
||||||
attacks = attacks > 0 ? attacks : 1;
|
attacks = attacks > 0 ? attacks : 1;
|
||||||
for(int i = 0; i < attacks; ++i) {
|
for(int i = 0; i < attacks; ++i) {
|
||||||
@ -1087,9 +1074,7 @@ void NPC::RangedAttack(Mob* other)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16 Mob::GetThrownDamage(int16 wDmg, int32& TotalDmg, int& minDmg)
|
uint16 Mob::GetThrownDamage(int16 wDmg, int32& TotalDmg, int& minDmg) {
|
||||||
{
|
|
||||||
|
|
||||||
uint16 MaxDmg = (((2 * wDmg) * GetDamageTable(SkillThrowing)) / 100);
|
uint16 MaxDmg = (((2 * wDmg) * GetDamageTable(SkillThrowing)) / 100);
|
||||||
|
|
||||||
if (MaxDmg == 0)
|
if (MaxDmg == 0)
|
||||||
@ -1101,8 +1086,7 @@ uint16 Mob::GetThrownDamage(int16 wDmg, int32& TotalDmg, int& minDmg)
|
|||||||
TotalDmg = MakeRandomInt(1, MaxDmg);
|
TotalDmg = MakeRandomInt(1, MaxDmg);
|
||||||
|
|
||||||
minDmg = 1;
|
minDmg = 1;
|
||||||
if(GetLevel() > 25)
|
if(GetLevel() > 25){
|
||||||
{
|
|
||||||
TotalDmg += ((GetLevel()-25)/3);
|
TotalDmg += ((GetLevel()-25)/3);
|
||||||
minDmg += ((GetLevel()-25)/3);
|
minDmg += ((GetLevel()-25)/3);
|
||||||
minDmg += minDmg * GetMeleeMinDamageMod_SE(SkillThrowing) / 100;
|
minDmg += minDmg * GetMeleeMinDamageMod_SE(SkillThrowing) / 100;
|
||||||
@ -1195,9 +1179,8 @@ void Client::ThrowingAttack(Mob* other, bool CanDoubleAttack) { //old was 51
|
|||||||
|
|
||||||
//consume ammo
|
//consume ammo
|
||||||
DeleteItemInInventory(ammo_slot, 1, true);
|
DeleteItemInInventory(ammo_slot, 1, true);
|
||||||
CheckIncreaseSkill(SkillThrowing, GetTarget());
|
CheckIncreaseSkill(SkillThrowing, GetTarget());
|
||||||
|
CommonBreakInvisible();
|
||||||
CommonBreakInvisible();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mob::DoThrowingAttackDmg(Mob* other, const ItemInst* RangeWeapon, const Item_Struct* item, uint16 weapon_damage, int16 chance_mod,int16 focus, int ReuseTime)
|
void Mob::DoThrowingAttackDmg(Mob* other, const ItemInst* RangeWeapon, const Item_Struct* item, uint16 weapon_damage, int16 chance_mod,int16 focus, int ReuseTime)
|
||||||
@ -1227,8 +1210,7 @@ void Mob::DoThrowingAttackDmg(Mob* other, const ItemInst* RangeWeapon, const Ite
|
|||||||
if (GetClass() == ROGUE && (BehindMob(other, GetX(), GetY())))
|
if (GetClass() == ROGUE && (BehindMob(other, GetX(), GetY())))
|
||||||
Assassinate_Dmg = TryAssassinate(other, SkillThrowing, ranged_timer.GetDuration());
|
Assassinate_Dmg = TryAssassinate(other, SkillThrowing, ranged_timer.GetDuration());
|
||||||
|
|
||||||
if(WDmg > 0)
|
if(WDmg > 0){
|
||||||
{
|
|
||||||
int minDmg = 1;
|
int minDmg = 1;
|
||||||
uint16 MaxDmg = GetThrownDamage(WDmg, TotalDmg, minDmg);
|
uint16 MaxDmg = GetThrownDamage(WDmg, TotalDmg, minDmg);
|
||||||
|
|
||||||
@ -1318,8 +1300,7 @@ void Mob::SendItemAnimation(Mob *to, const Item_Struct *item, SkillUseTypes skil
|
|||||||
safe_delete(outapp);
|
safe_delete(outapp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mob::ProjectileAnimation(Mob* to, int item_id, bool IsArrow, float speed, float angle, float tilt, float arc, const char *IDFile, SkillUseTypes skillInUse) {
|
void Mob::ProjectileAnimation(Mob* to, int item_id, bool IsArrow, float speed, float angle, float tilt, float arc, const char *IDFile, SkillUseTypes skillInUse) {
|
||||||
|
|
||||||
if (!to)
|
if (!to)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -1453,17 +1434,11 @@ void NPC::DoClassAttacks(Mob *target) {
|
|||||||
break;
|
break;
|
||||||
case MONK: case MONKGM: {
|
case MONK: case MONKGM: {
|
||||||
uint8 satype = SkillKick;
|
uint8 satype = SkillKick;
|
||||||
if(level > 29) {
|
if(level > 29) { satype = SkillFlyingKick; }
|
||||||
satype = SkillFlyingKick;
|
else if(level > 24) { satype = SkillDragonPunch; }
|
||||||
} else if(level > 24) {
|
else if(level > 19) { satype = SkillEagleStrike; }
|
||||||
satype = SkillDragonPunch;
|
else if(level > 9) { satype = SkillTigerClaw; }
|
||||||
} else if(level > 19) {
|
else if(level > 4) { satype = SkillRoundKick; }
|
||||||
satype = SkillEagleStrike;
|
|
||||||
} else if(level > 9) {
|
|
||||||
satype = SkillTigerClaw;
|
|
||||||
} else if(level > 4) {
|
|
||||||
satype = SkillRoundKick;
|
|
||||||
}
|
|
||||||
reuse = MonkSpecialAttack(target, satype);
|
reuse = MonkSpecialAttack(target, satype);
|
||||||
|
|
||||||
reuse *= 1000;
|
reuse *= 1000;
|
||||||
@ -1472,8 +1447,7 @@ void NPC::DoClassAttacks(Mob *target) {
|
|||||||
}
|
}
|
||||||
case WARRIOR: case WARRIORGM:{
|
case WARRIOR: case WARRIORGM:{
|
||||||
if(level >= RuleI(Combat, NPCBashKickLevel)){
|
if(level >= RuleI(Combat, NPCBashKickLevel)){
|
||||||
if(MakeRandomInt(0, 100) > 25) //tested on live, warrior mobs both kick and bash, kick about 75% of the time, casting doesn't seem to make a difference.
|
if(MakeRandomInt(0, 100) > 25){ //tested on live, warrior mobs both kick and bash, kick about 75% of the time, casting doesn't seem to make a difference.
|
||||||
{
|
|
||||||
DoAnim(animKick);
|
DoAnim(animKick);
|
||||||
int32 dmg = 0;
|
int32 dmg = 0;
|
||||||
|
|
||||||
@ -1494,8 +1468,7 @@ void NPC::DoClassAttacks(Mob *target) {
|
|||||||
DoSpecialAttackDamage(target, SkillKick, dmg, 1, -1, reuse);
|
DoSpecialAttackDamage(target, SkillKick, dmg, 1, -1, reuse);
|
||||||
did_attack = true;
|
did_attack = true;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
DoAnim(animTailRake);
|
DoAnim(animTailRake);
|
||||||
int32 dmg = 0;
|
int32 dmg = 0;
|
||||||
|
|
||||||
@ -1518,8 +1491,7 @@ void NPC::DoClassAttacks(Mob *target) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BERSERKER: case BERSERKERGM:
|
case BERSERKER: case BERSERKERGM:{
|
||||||
{
|
|
||||||
int AtkRounds = 3;
|
int AtkRounds = 3;
|
||||||
int32 max_dmg = 26 + ((GetLevel()-6) * 2);
|
int32 max_dmg = 26 + ((GetLevel()-6) * 2);
|
||||||
int32 min_dmg = 0;
|
int32 min_dmg = 0;
|
||||||
@ -1535,8 +1507,7 @@ void NPC::DoClassAttacks(Mob *target) {
|
|||||||
|
|
||||||
reuse = FrenzyReuseTime * 1000;
|
reuse = FrenzyReuseTime * 1000;
|
||||||
|
|
||||||
while(AtkRounds > 0) {
|
while(AtkRounds > 0) {
|
||||||
|
|
||||||
if (GetTarget() && (AtkRounds == 1 || MakeRandomInt(0,100) < 75)){
|
if (GetTarget() && (AtkRounds == 1 || MakeRandomInt(0,100) < 75)){
|
||||||
DoSpecialAttackDamage(GetTarget(), SkillFrenzy, max_dmg, min_dmg, -1 , reuse, true);
|
DoSpecialAttackDamage(GetTarget(), SkillFrenzy, max_dmg, min_dmg, -1 , reuse, true);
|
||||||
}
|
}
|
||||||
@ -1574,8 +1545,7 @@ void NPC::DoClassAttacks(Mob *target) {
|
|||||||
}
|
}
|
||||||
case CLERIC: case CLERICGM: //clerics can bash too.
|
case CLERIC: case CLERICGM: //clerics can bash too.
|
||||||
case SHADOWKNIGHT: case SHADOWKNIGHTGM:
|
case SHADOWKNIGHT: case SHADOWKNIGHTGM:
|
||||||
case PALADIN: case PALADINGM:
|
case PALADIN: case PALADINGM:{
|
||||||
{
|
|
||||||
if(level >= RuleI(Combat, NPCBashKickLevel)){
|
if(level >= RuleI(Combat, NPCBashKickLevel)){
|
||||||
DoAnim(animTailRake);
|
DoAnim(animTailRake);
|
||||||
int32 dmg = 0;
|
int32 dmg = 0;
|
||||||
@ -1615,8 +1585,7 @@ void Client::DoClassAttacks(Mob *ca_target, uint16 skill, bool IsRiposte)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
//check range for all these abilities, they are all close combat stuff
|
//check range for all these abilities, they are all close combat stuff
|
||||||
if(!CombatRange(ca_target))
|
if(!CombatRange(ca_target)){
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1638,10 +1607,8 @@ void Client::DoClassAttacks(Mob *ca_target, uint16 skill, bool IsRiposte)
|
|||||||
|
|
||||||
uint16 skill_to_use = -1;
|
uint16 skill_to_use = -1;
|
||||||
|
|
||||||
if (skill == -1){
|
if (skill == -1){
|
||||||
|
switch(GetClass()){
|
||||||
switch(GetClass())
|
|
||||||
{
|
|
||||||
case WARRIOR:
|
case WARRIOR:
|
||||||
case RANGER:
|
case RANGER:
|
||||||
case BEASTLORD:
|
case BEASTLORD:
|
||||||
@ -1692,14 +1659,11 @@ void Client::DoClassAttacks(Mob *ca_target, uint16 skill, bool IsRiposte)
|
|||||||
if(skill_to_use == -1)
|
if(skill_to_use == -1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(skill_to_use == SkillBash)
|
if(skill_to_use == SkillBash) {
|
||||||
{
|
if (ca_target!=this) {
|
||||||
if (ca_target!=this)
|
|
||||||
{
|
|
||||||
DoAnim(animTailRake);
|
DoAnim(animTailRake);
|
||||||
|
|
||||||
if(GetWeaponDamage(ca_target, GetInv().GetItem(MainSecondary)) <= 0 &&
|
if(GetWeaponDamage(ca_target, GetInv().GetItem(MainSecondary)) <= 0 && GetWeaponDamage(ca_target, GetInv().GetItem(MainShoulders)) <= 0){
|
||||||
GetWeaponDamage(ca_target, GetInv().GetItem(MainShoulders)) <= 0){
|
|
||||||
dmg = -5;
|
dmg = -5;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
@ -1720,16 +1684,14 @@ void Client::DoClassAttacks(Mob *ca_target, uint16 skill, bool IsRiposte)
|
|||||||
|
|
||||||
DoSpecialAttackDamage(ca_target, SkillBash, dmg, 1,-1,ReuseTime);
|
DoSpecialAttackDamage(ca_target, SkillBash, dmg, 1,-1,ReuseTime);
|
||||||
|
|
||||||
if(ReuseTime > 0 && !IsRiposte)
|
if(ReuseTime > 0 && !IsRiposte) {
|
||||||
{
|
|
||||||
p_timers.Start(pTimerCombatAbility, ReuseTime);
|
p_timers.Start(pTimerCombatAbility, ReuseTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(skill_to_use == SkillFrenzy)
|
if(skill_to_use == SkillFrenzy){
|
||||||
{
|
|
||||||
CheckIncreaseSkill(SkillFrenzy, GetTarget(), 10);
|
CheckIncreaseSkill(SkillFrenzy, GetTarget(), 10);
|
||||||
int AtkRounds = 3;
|
int AtkRounds = 3;
|
||||||
int skillmod = 100*GetSkill(SkillFrenzy)/MaxSkill(SkillFrenzy);
|
int skillmod = 100*GetSkill(SkillFrenzy)/MaxSkill(SkillFrenzy);
|
||||||
@ -1763,10 +1725,8 @@ void Client::DoClassAttacks(Mob *ca_target, uint16 skill, bool IsRiposte)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(skill_to_use == SkillKick)
|
if(skill_to_use == SkillKick){
|
||||||
{
|
if(ca_target!=this){
|
||||||
if(ca_target!=this)
|
|
||||||
{
|
|
||||||
DoAnim(animKick);
|
DoAnim(animKick);
|
||||||
|
|
||||||
if(GetWeaponDamage(ca_target, GetInv().GetItem(MainFeet)) <= 0){
|
if(GetWeaponDamage(ca_target, GetInv().GetItem(MainFeet)) <= 0){
|
||||||
@ -1790,12 +1750,7 @@ void Client::DoClassAttacks(Mob *ca_target, uint16 skill, bool IsRiposte)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(skill_to_use == SkillFlyingKick ||
|
if(skill_to_use == SkillFlyingKick || skill_to_use == SkillDragonPunch || skill_to_use == SkillEagleStrike || skill_to_use == SkillTigerClaw || skill_to_use == SkillRoundKick) {
|
||||||
skill_to_use == SkillDragonPunch ||
|
|
||||||
skill_to_use == SkillEagleStrike ||
|
|
||||||
skill_to_use == SkillTigerClaw ||
|
|
||||||
skill_to_use == SkillRoundKick)
|
|
||||||
{
|
|
||||||
ReuseTime = MonkSpecialAttack(ca_target, skill_to_use) - 1;
|
ReuseTime = MonkSpecialAttack(ca_target, skill_to_use) - 1;
|
||||||
MonkSpecialAttack(ca_target, skill_to_use);
|
MonkSpecialAttack(ca_target, skill_to_use);
|
||||||
|
|
||||||
@ -1809,8 +1764,7 @@ void Client::DoClassAttacks(Mob *ca_target, uint16 skill, bool IsRiposte)
|
|||||||
int MonkSPA [5] = { SkillFlyingKick, SkillDragonPunch, SkillEagleStrike, SkillTigerClaw, SkillRoundKick };
|
int MonkSPA [5] = { SkillFlyingKick, SkillDragonPunch, SkillEagleStrike, SkillTigerClaw, SkillRoundKick };
|
||||||
MonkSpecialAttack(ca_target, MonkSPA[MakeRandomInt(0,4)]);
|
MonkSpecialAttack(ca_target, MonkSPA[MakeRandomInt(0,4)]);
|
||||||
|
|
||||||
int TripleChance = 25;
|
int TripleChance = 25;
|
||||||
|
|
||||||
if (bDoubleSpecialAttack > 100)
|
if (bDoubleSpecialAttack > 100)
|
||||||
TripleChance += TripleChance*(100-bDoubleSpecialAttack)/100;
|
TripleChance += TripleChance*(100-bDoubleSpecialAttack)/100;
|
||||||
|
|
||||||
@ -1820,8 +1774,7 @@ void Client::DoClassAttacks(Mob *ca_target, uint16 skill, bool IsRiposte)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(skill_to_use == SkillBackstab)
|
if(skill_to_use == SkillBackstab){
|
||||||
{
|
|
||||||
ReuseTime = BackstabReuseTime-1;
|
ReuseTime = BackstabReuseTime-1;
|
||||||
|
|
||||||
if (IsRiposte)
|
if (IsRiposte)
|
||||||
@ -1831,8 +1784,7 @@ void Client::DoClassAttacks(Mob *ca_target, uint16 skill, bool IsRiposte)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ReuseTime = (ReuseTime*HasteMod)/100;
|
ReuseTime = (ReuseTime*HasteMod)/100;
|
||||||
if(ReuseTime > 0 && !IsRiposte)
|
if(ReuseTime > 0 && !IsRiposte){
|
||||||
{
|
|
||||||
p_timers.Start(pTimerCombatAbility, ReuseTime);
|
p_timers.Start(pTimerCombatAbility, ReuseTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1899,8 +1851,7 @@ void Mob::Taunt(NPC* who, bool always_succeed, float chance_bonus) {
|
|||||||
|
|
||||||
tauntchance /= 100.0f;
|
tauntchance /= 100.0f;
|
||||||
|
|
||||||
if (tauntchance > MakeRandomFloat(0, 1)) {
|
if (tauntchance > MakeRandomFloat(0, 1)) {
|
||||||
|
|
||||||
if (hate_top && hate_top != this){
|
if (hate_top && hate_top != this){
|
||||||
newhate = (who->GetNPCHate(hate_top) - who->GetNPCHate(this)) + 1;
|
newhate = (who->GetNPCHate(hate_top) - who->GetNPCHate(this)) + 1;
|
||||||
who->CastToNPC()->AddToHateList(this, newhate);
|
who->CastToNPC()->AddToHateList(this, newhate);
|
||||||
@ -1922,8 +1873,7 @@ void Mob::Taunt(NPC* who, bool always_succeed, float chance_bonus) {
|
|||||||
|
|
||||||
if (HasSkillProcs())
|
if (HasSkillProcs())
|
||||||
TrySkillProc(who, SkillTaunt, TauntReuseTime*1000);
|
TrySkillProc(who, SkillTaunt, TauntReuseTime*1000);
|
||||||
|
|
||||||
|
|
||||||
if (Success && HasSkillProcSuccess())
|
if (Success && HasSkillProcSuccess())
|
||||||
TrySkillProc(who, SkillTaunt, TauntReuseTime*1000, true);
|
TrySkillProc(who, SkillTaunt, TauntReuseTime*1000, true);
|
||||||
}
|
}
|
||||||
@ -1944,8 +1894,7 @@ void Mob::InstillDoubt(Mob *who) {
|
|||||||
if(!CombatRange(who))
|
if(!CombatRange(who))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(IsClient())
|
if(IsClient()) {
|
||||||
{
|
|
||||||
CastToClient()->CheckIncreaseSkill(SkillIntimidation, who, 10);
|
CastToClient()->CheckIncreaseSkill(SkillIntimidation, who, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1975,14 +1924,12 @@ void Mob::InstillDoubt(Mob *who) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 Mob::TryHeadShot(Mob* defender, SkillUseTypes skillInUse) {
|
uint32 Mob::TryHeadShot(Mob* defender, SkillUseTypes skillInUse) {
|
||||||
|
|
||||||
//Only works on YOUR target.
|
//Only works on YOUR target.
|
||||||
if(defender && (defender->GetBodyType() == BT_Humanoid) && !defender->IsClient()
|
if(defender && (defender->GetBodyType() == BT_Humanoid) && !defender->IsClient()
|
||||||
&& (skillInUse == SkillArchery) && (GetTarget() == defender)) {
|
&& (skillInUse == SkillArchery) && (GetTarget() == defender)) {
|
||||||
|
|
||||||
uint32 HeadShot_Dmg = aabonuses.HeadShot[1] + spellbonuses.HeadShot[1] + itembonuses.HeadShot[1];
|
uint32 HeadShot_Dmg = aabonuses.HeadShot[1] + spellbonuses.HeadShot[1] + itembonuses.HeadShot[1];
|
||||||
|
|
||||||
uint8 HeadShot_Level = 0; //Get Highest Headshot Level
|
uint8 HeadShot_Level = 0; //Get Highest Headshot Level
|
||||||
HeadShot_Level = aabonuses.HSLevel;
|
HeadShot_Level = aabonuses.HSLevel;
|
||||||
if (HeadShot_Level < spellbonuses.HSLevel)
|
if (HeadShot_Level < spellbonuses.HSLevel)
|
||||||
@ -1990,8 +1937,7 @@ uint32 Mob::TryHeadShot(Mob* defender, SkillUseTypes skillInUse) {
|
|||||||
else if (HeadShot_Level < itembonuses.HSLevel)
|
else if (HeadShot_Level < itembonuses.HSLevel)
|
||||||
HeadShot_Level = itembonuses.HSLevel;
|
HeadShot_Level = itembonuses.HSLevel;
|
||||||
|
|
||||||
if(HeadShot_Dmg && HeadShot_Level && (defender->GetLevel() <= HeadShot_Level)){
|
if(HeadShot_Dmg && HeadShot_Level && (defender->GetLevel() <= HeadShot_Level)){
|
||||||
|
|
||||||
float ProcChance = GetSpecialProcChances(MainRange);
|
float ProcChance = GetSpecialProcChances(MainRange);
|
||||||
if(ProcChance > MakeRandomFloat(0,1))
|
if(ProcChance > MakeRandomFloat(0,1))
|
||||||
return HeadShot_Dmg;
|
return HeadShot_Dmg;
|
||||||
@ -2084,7 +2030,7 @@ float Mob::GetAssassinateProcChances(uint16 ReuseTime)
|
|||||||
ProcChance += ProcChance * ProcBonus / 100.0f;
|
ProcChance += ProcChance * ProcBonus / 100.0f;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
/*Kayen: Unable to find data on old proc rate of assassinate, no idea if our formula is real or made up.*/
|
/* Kayen: Unable to find data on old proc rate of assassinate, no idea if our formula is real or made up. */
|
||||||
ProcChance = (10 + (static_cast<float>(mydex/10) + static_cast<float>(itembonuses.HeroicDEX /10)))/100.0f;
|
ProcChance = (10 + (static_cast<float>(mydex/10) + static_cast<float>(itembonuses.HeroicDEX /10)))/100.0f;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -2097,8 +2043,10 @@ void Mob::DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, SkillUseTypes
|
|||||||
if (!CanDoSpecialAttack(other))
|
if (!CanDoSpecialAttack(other))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//For spells using skill value 98 (feral swipe ect) server sets this to 67 automatically.
|
/*
|
||||||
//Kayen: This is unlikely to be completely accurate but use OFFENSE skill value for these effects.
|
For spells using skill value 98 (feral swipe ect) server sets this to 67 automatically.
|
||||||
|
Kayen: This is unlikely to be completely accurate but use OFFENSE skill value for these effects.
|
||||||
|
*/
|
||||||
if (skillinuse == SkillBegging)
|
if (skillinuse == SkillBegging)
|
||||||
skillinuse = SkillOffense;
|
skillinuse = SkillOffense;
|
||||||
|
|
||||||
@ -2107,8 +2055,7 @@ void Mob::DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, SkillUseTypes
|
|||||||
int Hand = MainPrimary;
|
int Hand = MainPrimary;
|
||||||
if (hate == 0 && weapon_damage > 1) hate = weapon_damage;
|
if (hate == 0 && weapon_damage > 1) hate = weapon_damage;
|
||||||
|
|
||||||
if(weapon_damage > 0){
|
if(weapon_damage > 0){
|
||||||
|
|
||||||
if (focus) //From FcBaseEffects
|
if (focus) //From FcBaseEffects
|
||||||
weapon_damage += weapon_damage*focus/100;
|
weapon_damage += weapon_damage*focus/100;
|
||||||
|
|
||||||
@ -2118,12 +2065,10 @@ void Mob::DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, SkillUseTypes
|
|||||||
}
|
}
|
||||||
|
|
||||||
int32 min_hit = 1;
|
int32 min_hit = 1;
|
||||||
int32 max_hit = (2*weapon_damage*GetDamageTable(skillinuse)) / 100;
|
int32 max_hit = (2 * weapon_damage*GetDamageTable(skillinuse)) / 100;
|
||||||
|
|
||||||
if(GetLevel() >= 28 && IsWarriorClass() )
|
|
||||||
{
|
|
||||||
int ucDamageBonus = GetWeaponDamageBonus((const Item_Struct*) nullptr );
|
|
||||||
|
|
||||||
|
if(GetLevel() >= 28 && IsWarriorClass() ) {
|
||||||
|
int ucDamageBonus = GetWeaponDamageBonus((const Item_Struct*) nullptr );
|
||||||
min_hit += (int) ucDamageBonus;
|
min_hit += (int) ucDamageBonus;
|
||||||
max_hit += (int) ucDamageBonus;
|
max_hit += (int) ucDamageBonus;
|
||||||
hate += ucDamageBonus;
|
hate += ucDamageBonus;
|
||||||
@ -2142,8 +2087,7 @@ void Mob::DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, SkillUseTypes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ApplySpecialAttackMod(skillinuse, max_hit, min_hit);
|
ApplySpecialAttackMod(skillinuse, max_hit, min_hit);
|
||||||
|
|
||||||
min_hit += min_hit * GetMeleeMinDamageMod_SE(skillinuse) / 100;
|
min_hit += min_hit * GetMeleeMinDamageMod_SE(skillinuse) / 100;
|
||||||
|
|
||||||
if(max_hit < min_hit)
|
if(max_hit < min_hit)
|
||||||
@ -2204,8 +2148,7 @@ void Mob::DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, SkillUseTypes
|
|||||||
TrySkillProc(other, skillinuse, ReuseTime, true);
|
TrySkillProc(other, skillinuse, ReuseTime, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Mob::CanDoSpecialAttack(Mob *other)
|
bool Mob::CanDoSpecialAttack(Mob *other) {
|
||||||
{
|
|
||||||
//Make sure everything is valid before doing any attacks.
|
//Make sure everything is valid before doing any attacks.
|
||||||
if (!other) {
|
if (!other) {
|
||||||
SetTarget(nullptr);
|
SetTarget(nullptr);
|
||||||
@ -2215,8 +2158,7 @@ bool Mob::CanDoSpecialAttack(Mob *other)
|
|||||||
if(!GetTarget())
|
if(!GetTarget())
|
||||||
SetTarget(other);
|
SetTarget(other);
|
||||||
|
|
||||||
if ((other == nullptr || ((IsClient() && CastToClient()->dead) || (other->IsClient() && other->CastToClient()->dead))
|
if ((other == nullptr || ((IsClient() && CastToClient()->dead) || (other->IsClient() && other->CastToClient()->dead)) || HasDied() || (!IsAttackAllowed(other)))) {
|
||||||
|| HasDied() || (!IsAttackAllowed(other)))) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -34,18 +34,16 @@ Copyright (C) 2001-2008 EQEMu Development Team (http://eqemulator.net)
|
|||||||
#include "../common/features.h"
|
#include "../common/features.h"
|
||||||
#include "quest_parser_collection.h"
|
#include "quest_parser_collection.h"
|
||||||
#include "mob.h"
|
#include "mob.h"
|
||||||
|
#include "queryserv.h"
|
||||||
|
|
||||||
|
extern QueryServ* QServ;
|
||||||
|
|
||||||
TaskManager::TaskManager() {
|
TaskManager::TaskManager() {
|
||||||
|
|
||||||
for(int i=0; i<MAXTASKS; i++)
|
for(int i=0; i<MAXTASKS; i++)
|
||||||
Tasks[i] = nullptr;
|
Tasks[i] = nullptr;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TaskManager::~TaskManager() {
|
TaskManager::~TaskManager() {
|
||||||
|
|
||||||
for(int i=0; i<MAXTASKS; i++) {
|
for(int i=0; i<MAXTASKS; i++) {
|
||||||
if(Tasks[i] != nullptr) {
|
if(Tasks[i] != nullptr) {
|
||||||
for(int j=0; j<Tasks[i]->ActivityCount; j++) {
|
for(int j=0; j<Tasks[i]->ActivityCount; j++) {
|
||||||
@ -62,11 +60,8 @@ TaskManager::~TaskManager() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool TaskManager::LoadTaskSets() {
|
bool TaskManager::LoadTaskSets() {
|
||||||
|
|
||||||
|
|
||||||
const char *TaskSetQuery = "SELECT `id`, `taskid` from `tasksets` WHERE `id` > 0 AND `id` < %i "
|
const char *TaskSetQuery = "SELECT `id`, `taskid` from `tasksets` WHERE `id` > 0 AND `id` < %i "
|
||||||
"AND `taskid` >= 0 AND `taskid` < %i ORDER BY `id`, `taskid` ASC";
|
"AND `taskid` >= 0 AND `taskid` < %i ORDER BY `id`, `taskid` ASC";
|
||||||
|
|
||||||
const char *ERR_MYSQLERROR = "[TASKS]Error in TaskManager::LoadTaskSets: %s";
|
const char *ERR_MYSQLERROR = "[TASKS]Error in TaskManager::LoadTaskSets: %s";
|
||||||
|
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||||
@ -1985,12 +1980,17 @@ void ClientTaskState::IncrementDoneCount(Client *c, TaskInformation* Task, int T
|
|||||||
// Inform the client the task has been updated, both by a chat message
|
// Inform the client the task has been updated, both by a chat message
|
||||||
c->Message(0, "Your task '%s' has been updated.", Task->Title);
|
c->Message(0, "Your task '%s' has been updated.", Task->Title);
|
||||||
|
|
||||||
if(Task->Activity[ActivityID].GoalMethod != METHODQUEST)
|
if(Task->Activity[ActivityID].GoalMethod != METHODQUEST) {
|
||||||
{
|
|
||||||
char buf[24];
|
char buf[24];
|
||||||
snprintf(buf, 23, "%d %d", ActiveTasks[TaskIndex].TaskID, ActiveTasks[TaskIndex].Activity[ActivityID].ActivityID);
|
snprintf(buf, 23, "%d %d", ActiveTasks[TaskIndex].TaskID, ActiveTasks[TaskIndex].Activity[ActivityID].ActivityID);
|
||||||
buf[23] = '\0';
|
buf[23] = '\0';
|
||||||
parse->EventPlayer(EVENT_TASK_STAGE_COMPLETE, c, buf, 0);
|
parse->EventPlayer(EVENT_TASK_STAGE_COMPLETE, c, buf, 0);
|
||||||
|
|
||||||
|
/* QS: PlayerLogTaskUpdates :: Update */
|
||||||
|
if (RuleB(QueryServ, PlayerLogTaskUpdates)){
|
||||||
|
std::string event_desc = StringFormat("Task Stage Complete :: taskid:%i activityid:%i donecount:%i in zoneid:%i instid:%i", ActiveTasks[TaskIndex].TaskID, ActiveTasks[TaskIndex].Activity[ActivityID].ActivityID, ActiveTasks[TaskIndex].Activity[ActivityID].DoneCount, c->GetZoneID(), c->GetInstanceID());
|
||||||
|
QServ->PlayerLogEvent(Player_Log_Task_Updates, c->CharacterID(), event_desc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this task is now complete, the Completed tasks will have been
|
// If this task is now complete, the Completed tasks will have been
|
||||||
@ -2002,6 +2002,12 @@ void ClientTaskState::IncrementDoneCount(Client *c, TaskInformation* Task, int T
|
|||||||
buf[23] = '\0';
|
buf[23] = '\0';
|
||||||
parse->EventPlayer(EVENT_TASK_COMPLETE, c, buf, 0);
|
parse->EventPlayer(EVENT_TASK_COMPLETE, c, buf, 0);
|
||||||
|
|
||||||
|
/* QS: PlayerLogTaskUpdates :: Complete */
|
||||||
|
if (RuleB(QueryServ, PlayerLogTaskUpdates)){
|
||||||
|
std::string event_desc = StringFormat("Task Complete :: taskid:%i activityid:%i donecount:%i in zoneid:%i instid:%i", ActiveTasks[TaskIndex].TaskID, ActiveTasks[TaskIndex].Activity[ActivityID].ActivityID, ActiveTasks[TaskIndex].Activity[ActivityID].DoneCount, c->GetZoneID(), c->GetInstanceID());
|
||||||
|
QServ->PlayerLogEvent(Player_Log_Task_Updates, c->CharacterID(), event_desc);
|
||||||
|
}
|
||||||
|
|
||||||
taskmanager->SendCompletedTasksToClient(c, this);
|
taskmanager->SendCompletedTasksToClient(c, this);
|
||||||
c->SendTaskActivityComplete(ActiveTasks[TaskIndex].TaskID, 0, TaskIndex, false);
|
c->SendTaskActivityComplete(ActiveTasks[TaskIndex].TaskID, 0, TaskIndex, false);
|
||||||
taskmanager->SaveClientState(c, this);
|
taskmanager->SaveClientState(c, this);
|
||||||
@ -2011,6 +2017,7 @@ void ClientTaskState::IncrementDoneCount(Client *c, TaskInformation* Task, int T
|
|||||||
// If Experience and/or cash rewards are set, reward them from the task even if RewardMethod is METHODQUEST
|
// If Experience and/or cash rewards are set, reward them from the task even if RewardMethod is METHODQUEST
|
||||||
RewardTask(c, Task);
|
RewardTask(c, Task);
|
||||||
//RemoveTask(c, TaskIndex);
|
//RemoveTask(c, TaskIndex);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -34,6 +34,9 @@
|
|||||||
#include "../common/string_util.h"
|
#include "../common/string_util.h"
|
||||||
#include "../common/rulesys.h"
|
#include "../common/rulesys.h"
|
||||||
#include "quest_parser_collection.h"
|
#include "quest_parser_collection.h"
|
||||||
|
#include "queryserv.h"
|
||||||
|
|
||||||
|
extern QueryServ* QServ;
|
||||||
|
|
||||||
static const SkillUseTypes TradeskillUnknown = Skill1HBlunt; /* an arbitrary non-tradeskill */
|
static const SkillUseTypes TradeskillUnknown = Skill1HBlunt; /* an arbitrary non-tradeskill */
|
||||||
|
|
||||||
@ -1067,7 +1070,7 @@ bool Client::TradeskillExecute(DBTradeskillRecipe_Struct *spec) {
|
|||||||
if(over_trivial < 0)
|
if(over_trivial < 0)
|
||||||
CheckIncreaseTradeskill(bonusstat, stat_modifier, skillup_modifier, success_modifier, spec->tradeskill);
|
CheckIncreaseTradeskill(bonusstat, stat_modifier, skillup_modifier, success_modifier, spec->tradeskill);
|
||||||
|
|
||||||
Message_StringID(4,TRADESKILL_SUCCEED,spec->name.c_str());
|
Message_StringID(4, TRADESKILL_SUCCEED, spec->name.c_str());
|
||||||
|
|
||||||
_log(TRADESKILLS__TRACE, "Tradeskill success");
|
_log(TRADESKILLS__TRACE, "Tradeskill success");
|
||||||
|
|
||||||
@ -1076,16 +1079,24 @@ bool Client::TradeskillExecute(DBTradeskillRecipe_Struct *spec) {
|
|||||||
//should we check this crap?
|
//should we check this crap?
|
||||||
SummonItem(itr->first, itr->second);
|
SummonItem(itr->first, itr->second);
|
||||||
item = database.GetItem(itr->first);
|
item = database.GetItem(itr->first);
|
||||||
if (this->GetGroup())
|
if (this->GetGroup()) {
|
||||||
{
|
entity_list.MessageGroup(this, true, MT_Skills, "%s has successfully fashioned %s!", GetName(), item->Name);
|
||||||
entity_list.MessageGroup(this,true,MT_Skills,"%s has successfully fashioned %s!",GetName(),item->Name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* QS: Player_Log_Trade_Skill_Events */
|
||||||
|
if (RuleB(QueryServ, PlayerLogTradeSkillEvents)){
|
||||||
|
std::string event_desc = StringFormat("Success :: fashioned recipe_id:%i tskillid:%i trivial:%i chance:%4.2f in zoneid:%i instid:%i", spec->recipe_id, spec->tradeskill, spec->trivial, chance, this->GetZoneID(), this->GetInstanceID());
|
||||||
|
QServ->PlayerLogEvent(Player_Log_Trade_Skill_Events, this->CharacterID(), event_desc);
|
||||||
|
}
|
||||||
|
|
||||||
if(RuleB(TaskSystem, EnableTaskSystem))
|
if(RuleB(TaskSystem, EnableTaskSystem))
|
||||||
UpdateTasksForItem(ActivityTradeSkill, itr->first, itr->second);
|
UpdateTasksForItem(ActivityTradeSkill, itr->first, itr->second);
|
||||||
++itr;
|
++itr;
|
||||||
}
|
}
|
||||||
return(true);
|
return(true);
|
||||||
} else {
|
}
|
||||||
|
/* Tradeskill Fail */
|
||||||
|
else {
|
||||||
success_modifier = 2; // Halves the chance
|
success_modifier = 2; // Halves the chance
|
||||||
|
|
||||||
if(over_trivial < 0)
|
if(over_trivial < 0)
|
||||||
@ -1097,6 +1108,13 @@ bool Client::TradeskillExecute(DBTradeskillRecipe_Struct *spec) {
|
|||||||
if (this->GetGroup())
|
if (this->GetGroup())
|
||||||
{
|
{
|
||||||
entity_list.MessageGroup(this,true,MT_Skills,"%s was unsuccessful in %s tradeskill attempt.",GetName(),this->GetGender() == 0 ? "his" : this->GetGender() == 1 ? "her" : "its");
|
entity_list.MessageGroup(this,true,MT_Skills,"%s was unsuccessful in %s tradeskill attempt.",GetName(),this->GetGender() == 0 ? "his" : this->GetGender() == 1 ? "her" : "its");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* QS: Player_Log_Trade_Skill_Events */
|
||||||
|
if (RuleB(QueryServ, PlayerLogTradeSkillEvents)){
|
||||||
|
std::string event_desc = StringFormat("Failed :: recipe_id:%i tskillid:%i trivial:%i chance:%4.2f in zoneid:%i instid:%i", spec->recipe_id, spec->tradeskill, spec->trivial, chance, this->GetZoneID(), this->GetInstanceID());
|
||||||
|
QServ->PlayerLogEvent(Player_Log_Trade_Skill_Events, this->CharacterID(), event_desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
itr = spec->onfail.begin();
|
itr = spec->onfail.begin();
|
||||||
@ -1106,6 +1124,8 @@ bool Client::TradeskillExecute(DBTradeskillRecipe_Struct *spec) {
|
|||||||
++itr;
|
++itr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Salvage Item rolls */
|
||||||
|
|
||||||
// Rolls on each item, is possible to return everything
|
// Rolls on each item, is possible to return everything
|
||||||
int SalvageChance = aabonuses.SalvageChance + itembonuses.SalvageChance + spellbonuses.SalvageChance;
|
int SalvageChance = aabonuses.SalvageChance + itembonuses.SalvageChance + spellbonuses.SalvageChance;
|
||||||
// Skip check if not a normal TS or if a quest recipe these should be nofail, but check amyways
|
// Skip check if not a normal TS or if a quest recipe these should be nofail, but check amyways
|
||||||
|
|||||||
@ -262,45 +262,36 @@ Mob* EntityList::GetTrapTrigger(Trap* trap) {
|
|||||||
|
|
||||||
//todo: rewrite this to not need direct access to trap members.
|
//todo: rewrite this to not need direct access to trap members.
|
||||||
bool ZoneDatabase::LoadTraps(const char* zonename, int16 version) {
|
bool ZoneDatabase::LoadTraps(const char* zonename, int16 version) {
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
|
||||||
char *query = 0;
|
|
||||||
MYSQL_RES *result;
|
|
||||||
MYSQL_ROW row;
|
|
||||||
|
|
||||||
// int char_num = 0;
|
std::string query = StringFormat("SELECT id, x, y, z, effect, effectvalue, effectvalue2, skill, "
|
||||||
unsigned long* lengths;
|
"maxzdiff, radius, chance, message, respawn_time, respawn_var, level "
|
||||||
|
"FROM traps WHERE zone='%s' AND version=%u", zonename, version);
|
||||||
if (RunQuery(query, MakeAnyLenString(&query, "SELECT id,x,y,z,effect,effectvalue,effectvalue2,skill,maxzdiff,radius,chance,message,respawn_time,respawn_var,level FROM traps WHERE zone='%s' AND version=%u", zonename, version), errbuf, &result)) {
|
auto results = QueryDatabase(query);
|
||||||
safe_delete_array(query);
|
if (!results.Success()) {
|
||||||
while ((row = mysql_fetch_row(result)))
|
LogFile->write(EQEMuLog::Error, "Error in LoadTraps query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||||
{
|
|
||||||
lengths = mysql_fetch_lengths(result);
|
|
||||||
Trap* trap = new Trap();
|
|
||||||
trap->trap_id = atoi(row[0]);
|
|
||||||
trap->x = atof(row[1]);
|
|
||||||
trap->y = atof(row[2]);
|
|
||||||
trap->z = atof(row[3]);
|
|
||||||
trap->effect = atoi(row[4]);
|
|
||||||
trap->effectvalue = atoi(row[5]);
|
|
||||||
trap->effectvalue2 = atoi(row[6]);
|
|
||||||
trap->skill = atoi(row[7]);
|
|
||||||
trap->maxzdiff = atof(row[8]);
|
|
||||||
trap->radius = atof(row[9]);
|
|
||||||
trap->chance = atoi(row[10]);
|
|
||||||
trap->message = row[11];
|
|
||||||
trap->respawn_time = atoi(row[12]);
|
|
||||||
trap->respawn_var = atoi(row[13]);
|
|
||||||
trap->level = atoi(row[14]);
|
|
||||||
entity_list.AddTrap(trap);
|
|
||||||
trap->CreateHiddenTrigger();
|
|
||||||
}
|
|
||||||
mysql_free_result(result);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
LogFile->write(EQEMuLog::Error, "Error in LoadTraps query '%s': %s", query, errbuf);
|
|
||||||
safe_delete_array(query);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
|
Trap* trap = new Trap();
|
||||||
|
trap->trap_id = atoi(row[0]);
|
||||||
|
trap->x = atof(row[1]);
|
||||||
|
trap->y = atof(row[2]);
|
||||||
|
trap->z = atof(row[3]);
|
||||||
|
trap->effect = atoi(row[4]);
|
||||||
|
trap->effectvalue = atoi(row[5]);
|
||||||
|
trap->effectvalue2 = atoi(row[6]);
|
||||||
|
trap->skill = atoi(row[7]);
|
||||||
|
trap->maxzdiff = atof(row[8]);
|
||||||
|
trap->radius = atof(row[9]);
|
||||||
|
trap->chance = atoi(row[10]);
|
||||||
|
trap->message = row[11];
|
||||||
|
trap->respawn_time = atoi(row[12]);
|
||||||
|
trap->respawn_var = atoi(row[13]);
|
||||||
|
trap->level = atoi(row[14]);
|
||||||
|
entity_list.AddTrap(trap);
|
||||||
|
trap->CreateHiddenTrigger();
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -378,68 +378,60 @@ void Client::SendGuildTributes() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool ZoneDatabase::LoadTributes() {
|
bool ZoneDatabase::LoadTributes() {
|
||||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
|
||||||
MYSQL_RES *result;
|
|
||||||
MYSQL_ROW row;
|
|
||||||
|
|
||||||
TributeData t;
|
TributeData tributeData;
|
||||||
memset(&t.tiers, 0, sizeof(t.tiers));
|
memset(&tributeData.tiers, 0, sizeof(tributeData.tiers));
|
||||||
t.tier_count = 0;
|
tributeData.tier_count = 0;
|
||||||
|
|
||||||
tribute_list.clear();
|
tribute_list.clear();
|
||||||
|
|
||||||
const char *query = "SELECT id,name,descr,unknown,isguild FROM tributes";
|
const std::string query = "SELECT id, name, descr, unknown, isguild FROM tributes";
|
||||||
if (RunQuery(query, strlen(query), errbuf, &result)) {
|
auto results = QueryDatabase(query);
|
||||||
int r;
|
if (!results.Success()) {
|
||||||
while ((row = mysql_fetch_row(result))) {
|
LogFile->write(EQEMuLog::Error, "Error in LoadTributes first query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||||
r = 0;
|
|
||||||
uint32 id = atoul(row[r++]);
|
|
||||||
t.name = row[r++];
|
|
||||||
t.description = row[r++];
|
|
||||||
t.unknown = strtoul(row[r++], nullptr, 10);
|
|
||||||
t.is_guild = atol(row[r++])==0?false:true;
|
|
||||||
|
|
||||||
tribute_list[id] = t;
|
|
||||||
}
|
|
||||||
mysql_free_result(result);
|
|
||||||
} else {
|
|
||||||
LogFile->write(EQEMuLog::Error, "Error in LoadTributes first query '%s': %s", query, errbuf);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
|
uint32 id = atoul(row[0]);
|
||||||
|
tributeData.name = row[1];
|
||||||
|
tributeData.description = row[2];
|
||||||
|
tributeData.unknown = strtoul(row[3], nullptr, 10);
|
||||||
|
tributeData.is_guild = atol(row[4]) == 0? false: true;
|
||||||
|
|
||||||
const char *query2 = "SELECT tribute_id,level,cost,item_id FROM tribute_levels ORDER BY tribute_id,level";
|
tribute_list[id] = tributeData;
|
||||||
if (RunQuery(query2, strlen(query2), errbuf, &result)) {
|
}
|
||||||
int r;
|
|
||||||
while ((row = mysql_fetch_row(result))) {
|
|
||||||
r = 0;
|
|
||||||
uint32 id = atoul(row[r++]);
|
|
||||||
|
|
||||||
if(tribute_list.count(id) != 1) {
|
const std::string query2 = "SELECT tribute_id, level, cost, item_id FROM tribute_levels ORDER BY tribute_id, level";
|
||||||
LogFile->write(EQEMuLog::Error, "Error in LoadTributes: unknown tribute %lu in tribute_levels", (unsigned long)id);
|
results = QueryDatabase(query2);
|
||||||
continue;
|
if (!results.Success()) {
|
||||||
}
|
LogFile->write(EQEMuLog::Error, "Error in LoadTributes level query '%s': %s", query.c_str(), results.ErrorMessage().c_str());
|
||||||
|
|
||||||
TributeData &cur = tribute_list[id];
|
|
||||||
|
|
||||||
if(cur.tier_count >= MAX_TRIBUTE_TIERS) {
|
|
||||||
LogFile->write(EQEMuLog::Error, "Error in LoadTributes: on tribute %lu: more tiers defined than permitted", (unsigned long)id);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
TributeLevel_Struct &s = cur.tiers[cur.tier_count];
|
|
||||||
|
|
||||||
s.level = atoul(row[r++]);
|
|
||||||
s.cost = atoul(row[r++]);
|
|
||||||
s.tribute_item_id = atoul(row[r++]);
|
|
||||||
cur.tier_count++;
|
|
||||||
}
|
|
||||||
mysql_free_result(result);
|
|
||||||
} else {
|
|
||||||
LogFile->write(EQEMuLog::Error, "Error in LoadTributes level query '%s': %s", query, errbuf);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||||
|
uint32 id = atoul(row[0]);
|
||||||
|
|
||||||
|
if(tribute_list.count(id) != 1) {
|
||||||
|
LogFile->write(EQEMuLog::Error, "Error in LoadTributes: unknown tribute %lu in tribute_levels", (unsigned long)id);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
TributeData &cur = tribute_list[id];
|
||||||
|
|
||||||
|
if(cur.tier_count >= MAX_TRIBUTE_TIERS) {
|
||||||
|
LogFile->write(EQEMuLog::Error, "Error in LoadTributes: on tribute %lu: more tiers defined than permitted", (unsigned long)id);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
TributeLevel_Struct &s = cur.tiers[cur.tier_count];
|
||||||
|
|
||||||
|
s.level = atoul(row[1]);
|
||||||
|
s.cost = atoul(row[2]);
|
||||||
|
s.tribute_item_id = atoul(row[3]);
|
||||||
|
cur.tier_count++;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3226,3 +3226,11 @@ bool ZoneDatabase::GetFactionIdsForNPC(uint32 nfl_id, std::list<struct NPCFactio
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ZoneDatabase::StoreCharacterLookup(uint32 char_id) {
|
||||||
|
std::string c_lookup = StringFormat("REPLACE INTO `character_lookup` (id, account_id, `name`, timelaston, x, y, z, zonename, zoneid, instanceid, pktime, groupid, class, `level`, lfp, lfg, mailkey, xtargets, firstlogon, inspectmessage)"
|
||||||
|
" SELECT id, account_id, `name`, timelaston, x, y, z, zonename, zoneid, instanceid, pktime, groupid, class, `level`, lfp, lfg, mailkey, xtargets, firstlogon, inspectmessage"
|
||||||
|
" FROM `character_` "
|
||||||
|
" WHERE `id` = %i ", char_id);
|
||||||
|
QueryDatabase(c_lookup);
|
||||||
|
}
|
||||||
@ -246,6 +246,7 @@ public:
|
|||||||
/*
|
/*
|
||||||
* General Character Related Stuff
|
* General Character Related Stuff
|
||||||
*/
|
*/
|
||||||
|
void StoreCharacterLookup(uint32 char_id);
|
||||||
bool SetServerFilters(char* name, ServerSideFilters_Struct *ssfs);
|
bool SetServerFilters(char* name, ServerSideFilters_Struct *ssfs);
|
||||||
uint32 GetServerFilters(char* name, ServerSideFilters_Struct *ssfs);
|
uint32 GetServerFilters(char* name, ServerSideFilters_Struct *ssfs);
|
||||||
bool GetAccountInfoForLogin(uint32 account_id, int16* admin = 0, char* account_name = 0,
|
bool GetAccountInfoForLogin(uint32 account_id, int16* admin = 0, char* account_name = 0,
|
||||||
|
|||||||
@ -25,7 +25,9 @@
|
|||||||
#include "../common/string_util.h"
|
#include "../common/string_util.h"
|
||||||
#include "string_ids.h"
|
#include "string_ids.h"
|
||||||
#include "quest_parser_collection.h"
|
#include "quest_parser_collection.h"
|
||||||
|
#include "queryserv.h"
|
||||||
|
|
||||||
|
extern QueryServ* QServ;
|
||||||
extern WorldServer worldserver;
|
extern WorldServer worldserver;
|
||||||
extern Zone* zone;
|
extern Zone* zone;
|
||||||
|
|
||||||
@ -147,7 +149,7 @@ void Client::Handle_OP_ZoneChange(const EQApplicationPacket *app) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//make sure its a valid zone.
|
/* Check for Valid Zone */
|
||||||
const char *target_zone_name = database.GetZoneName(target_zone_id);
|
const char *target_zone_name = database.GetZoneName(target_zone_id);
|
||||||
if(target_zone_name == nullptr) {
|
if(target_zone_name == nullptr) {
|
||||||
//invalid zone...
|
//invalid zone...
|
||||||
@ -157,7 +159,7 @@ void Client::Handle_OP_ZoneChange(const EQApplicationPacket *app) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//load up the safe coords, restrictions, and verify the zone name
|
/* Load up the Safe Coordinates, restrictions and verify the zone name*/
|
||||||
float safe_x, safe_y, safe_z;
|
float safe_x, safe_y, safe_z;
|
||||||
int16 minstatus = 0;
|
int16 minstatus = 0;
|
||||||
uint8 minlevel = 0;
|
uint8 minlevel = 0;
|
||||||
@ -327,15 +329,19 @@ void Client::DoZoneSuccess(ZoneChange_Struct *zc, uint16 zone_id, uint32 instanc
|
|||||||
|
|
||||||
SendLogoutPackets();
|
SendLogoutPackets();
|
||||||
|
|
||||||
//dont clear aggro until the zone is successful
|
/* QS: PlayerLogZone */
|
||||||
|
if (RuleB(QueryServ, PlayerLogZone)){
|
||||||
|
std::string event_desc = StringFormat("Zoning :: zoneid:%u instid:%u x:%4.2f y:%4.2f z:%4.2f h:%4.2f zonemode:%d from zoneid:%u instid:%i", zone_id, instance_id, dest_x, dest_y, dest_z, dest_h, zone_mode, this->GetZoneID(), this->GetInstanceID());
|
||||||
|
QServ->PlayerLogEvent(Player_Log_Zoning, this->CharacterID(), event_desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dont clear aggro until the zone is successful */
|
||||||
entity_list.RemoveFromHateLists(this);
|
entity_list.RemoveFromHateLists(this);
|
||||||
|
|
||||||
if(this->GetPet())
|
if(this->GetPet())
|
||||||
entity_list.RemoveFromHateLists(this->GetPet());
|
entity_list.RemoveFromHateLists(this->GetPet());
|
||||||
|
|
||||||
LogFile->write(EQEMuLog::Status, "Zoning '%s' to: %s (%i) - (%i) x=%f, y=%f, z=%f",
|
LogFile->write(EQEMuLog::Status, "Zoning '%s' to: %s (%i) - (%i) x=%f, y=%f, z=%f", m_pp.name, database.GetZoneName(zone_id), zone_id, instance_id, dest_x, dest_y, dest_z);
|
||||||
m_pp.name, database.GetZoneName(zone_id), zone_id, instance_id,
|
|
||||||
dest_x, dest_y, dest_z);
|
|
||||||
|
|
||||||
//set the player's coordinates in the new zone so they have them
|
//set the player's coordinates in the new zone so they have them
|
||||||
//when they zone into it
|
//when they zone into it
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user