Compare commits

..

21 Commits

Author SHA1 Message Date
Michael Cook (mackal) da121137e5 Fix logging macros
macros should be fully wrapped in do { ... } while(false) to prevent
any accidental coding issues (like else being eaten!!!)
2014-09-05 13:26:44 -04:00
Michael Cook (mackal) c953f1dee1 Merge pull request #244 from addtheice/merc_stance_fix
Fix iterator on mercstance crash bug
2014-09-05 02:30:13 -04:00
Arthur Ice 32b595afb4 Fix iterator on mercstance crash bug 2014-09-04 23:15:20 -07:00
Uleat 37d3daaf9a Client timer issue fix 2014-09-03 23:59:55 -04:00
Michael Cook (mackal) 22742b6a25 Add #shownumhits workaround command to show numhits 2014-09-03 23:50:23 -04:00
SecretsOTheP 891952eb79 Bot fixes for previous commit 2014-09-03 18:34:31 -04:00
SecretsOTheP e6a0b01f37 Identified the routines needed to augment items in RoF. Currently, only Insert and Remove are supported. Swap and Destroy do not work due to missing functions related to the cursor. 2014-09-03 18:25:21 -04:00
SecretsOTheP 64c324a42b changelog.txt 2014-09-02 22:09:38 -04:00
SecretsOTheP f909e76260 Merge branch 'master' of https://github.com/EQEmu/Server 2014-09-02 22:08:47 -04:00
SecretsOTheP b7dfdc5060 Oops. 2014-09-02 22:07:49 -04:00
Uleat e25239a50d Merge branch 'master' of https://github.com/EQEmu/Server 2014-09-02 21:20:06 -04:00
Uleat 76d3edc534 Changed #loc to report the same precision as /loc for Cartesians 2014-09-02 21:19:30 -04:00
SecretsOTheP 7301182b3e Merge branch 'master' of https://github.com/EQEmu/Server
Conflicts:
	changelog.txt
2014-09-02 21:18:30 -04:00
SecretsOTheP 832e5e90d1 Secrets: Identified OP_GuildPromote for RoF clients.
Secrets: Fixed promotion, demotion, transferring a leader and displaying of client ranks in the Rain of Fear client. The rain of fear client, as such, will only have 3 ranks like the other clients, but supports a theoretical 8 ranks later.
Secrets/Akkadius: Fixed an issue involving character name lookup in the new DB code.
2014-09-02 21:16:20 -04:00
Michael Cook (mackal) 7ddaabee30 Merge pull request #235 from addtheice/guild_mgr_patch
Fixed bug with loading failing on Guild bank areas
2014-09-02 16:11:05 -04:00
Arthur Dene Ice 41d57ddab6 Fixed bug with loading failing on Guild bank areas 2014-09-02 12:43:56 -07:00
Michael Cook (mackal) 8dd00f5288 Fix crash issue in zone/hate_list.cpp 2014-09-02 02:39:03 -04:00
KimLS 15f217b594 Fixed non-conforming sql files. 2014-09-01 15:48:22 -07:00
Michael Cook (mackal) 8422178233 Fix issue with requesting an adventure 2014-09-01 02:58:52 -04:00
Uleat eebe902917 Script update for opcode_handlers.py - changes in file names. 2014-09-01 00:07:21 -04:00
KimLS 04dc593df9 Various bug fixes 2014-08-31 20:27:02 -07:00
39 changed files with 443 additions and 106 deletions
+19
View File
@@ -1,5 +1,24 @@
EQEMu Changelog (Started on Sept 24, 2003 15:50)
-------------------------------------------------------
== 09/03/2014 ==
Secrets: Identified the routines needed to augment items in RoF. Currently, only Insert and Remove are supported. Swap and Destroy do not work due to missing functions related to the cursor.
demonstar55: Added work around command to show numhits on your buffs (#shownumhits)
Uleat: Fix for timer issue introduced by Zone::ShutDown() fix.
== 09/02/2014 ==
Secrets: Identified OP_GuildPromote for RoF clients.
Secrets: Fixed promotion, demotion, transferring a leader and displaying of client ranks in the Rain of Fear client. The rain of fear client, as such, will only have 3 ranks like the other clients, but supports a theoretical 8 ranks later.
Secrets/Akkadius: Fixed an issue involving character name lookup in the new DB code.
demonstar55: crash fix checking DivineAura in hate_list.cpp
Secrets: Reverted some code that got in the main branch that shouldn't have gotten there.
Uleat: Changed #loc to report the same precision as /loc for Cartesians
== 08/31/2014 ==
KLS: Fixed a bug in fishing in S3D zones
KLS: Fixed a bug in turnins with new any abstraction
KLS: Fixed a few quest related inconsistencies.
KLS: Added Lua EntityList::ChannelMessage(from, type, msg, language)
== 08/30/2014 ==
demonstar55: (noudess) Merchants should be more descriptive of why they don't sell to you
+3 -1
View File
@@ -771,7 +771,9 @@ void Database::GetCharName(uint32 char_id, char* name) {
}
auto row = results.begin();
strcpy(name, row[0]);
for (auto row = results.begin(); row != results.end(); ++row) {
strcpy(name, row[0]);
}
}
bool Database::LoadVariables() {
+1
View File
@@ -540,3 +540,4 @@ N(OP_OpenInventory),
N(OP_OpenContainer),
N(OP_Marquee),
N(OP_ClientTimeStamp),
N(OP_GuildPromote),
+15 -4
View File
@@ -2287,10 +2287,13 @@ struct Stun_Struct { // 4 bytes total
};
struct AugmentItem_Struct {
/*00*/ int16 container_slot;
/*02*/ char unknown02[2];
/*04*/ int32 augment_slot;
/*08*/
/*00*/ uint32 container_index;
/*04*/ int32 container_slot;
/*08*/ uint32 augment_index;
/*12*/ int32 augment_slot;
/*16*/ uint32 dest_inst_id; // The unique serial number for the item instance that is being augmented
/*20*/ int32 augment_action; // Guessed - 0 = augment, 1 = remove with distiller, 3 = delete aug
/*24*/
};
// OP_Emote
@@ -4461,6 +4464,14 @@ struct GuildBankPromote_Struct
/*12*/ uint32 Slot2; // Always appears to be the same as Slot for Action code 3
};
struct GuildPromoteStruct {
/*000*/ char target[64];
/*064*/ char name[64];
/*128*/ uint32 rank;
/*132*/ uint32 myrank;
/*136*/
};
struct GuildBankPermissions_Struct
{
/*00*/ uint32 Action; // 6
+1 -1
View File
@@ -534,7 +534,7 @@ void EQStream::FastQueuePacket(EQApplicationPacket **p, bool ack_req)
uint16 opcode = (*OpMgr)->EmuToEQ(pack->emu_opcode);
_log(NET__APP_TRACE, "Queueing %sacked packet with opcode 0x%x (%s) and length %d", ack_req?"":"non-", opcode, OpcodeManager::EmuToName(pack->emu_opcode), pack->size);
//_log(NET__APP_TRACE, "Queueing %sacked packet with opcode 0x%x (%s) and length %d", ack_req?"":"non-", opcode, OpcodeManager::EmuToName(pack->emu_opcode), pack->size);
if (!ack_req) {
NonSequencedPush(new EQProtocolPacket(opcode, pack->pBuffer, pack->size));
+5
View File
@@ -474,6 +474,11 @@ bool BaseGuildManager::SetBankerFlag(uint32 charid, bool is_banker) {
return(true);
}
bool BaseGuildManager::ForceRankUpdate(uint32 charid) {
SendRankUpdate(charid);
return(true);
}
bool BaseGuildManager::SetAltFlag(uint32 charid, bool is_alt)
{
if(!DBSetAltFlag(charid, is_alt))
+1
View File
@@ -54,6 +54,7 @@ public:
bool SetGuild(uint32 charid, uint32 guild_id, uint8 rank);
bool SetGuildRank(uint32 charid, uint8 rank);
bool SetBankerFlag(uint32 charid, bool is_banker);
bool ForceRankUpdate(uint32 charid);
bool GetAltFlag(uint32 CharID);
bool SetAltFlag(uint32 charid, bool is_alt);
bool GetBankerFlag(uint32 CharID);
+3 -3
View File
@@ -92,8 +92,8 @@ extern void log_raw_packet(LogType type, uint16 seq, const BasePacket *p);
class Mob;
extern void log_message_mob(LogType type, Mob *who, const char *fmt, ...);
#define mlog( type, format, ...) \
if(IsLoggingEnabled()) \
do { \
if(IsLoggingEnabled()) \
if(log_type_info[ type ].enabled) { \
log_message_mob(type, this, format, ##__VA_ARGS__); \
} \
@@ -150,16 +150,16 @@ extern void log_raw_packet(LogType type, uint16 seq, const BasePacket *p);
class Mob;
extern void log_hex_mob(LogType type, Mob *who, const char *data, uint32 length);
#define mhex( type, data, len) \
if(IsLoggingEnabled()) \
do { \
if(IsLoggingEnabled()) \
if(log_type_info[ type ].enabled) { \
log_hex_mob(type, this, data, len); \
} \
} while(false)
extern void log_packet_mob(LogType type, Mob *who, const BasePacket *p);
#define mpkt( type, packet) \
if(IsLoggingEnabled()) \
do { \
if(IsLoggingEnabled()) \
if(log_type_info[ type ].enabled) { \
log_packet_mob(type, this, packet); \
} \
+32 -7
View File
@@ -1,4 +1,3 @@
#include "../debug.h"
#include "rof.h"
#include "../opcodemgr.h"
@@ -1974,7 +1973,14 @@ ENCODE(OP_ZoneSpawns)
else
{
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->guildID);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->guildrank);
/* Translate older ranks to new values */
switch (emu->guildrank) {
case 0: { VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 5); break; } // GUILD_MEMBER 0
case 1: { VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 3); break; } // GUILD_OFFICER 1
case 2: { VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 1); break; } // GUILD_LEADER 2
default: { VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->guildrank); break; } //
}
}
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, emu->class_);
@@ -2406,7 +2412,15 @@ ENCODE(OP_GuildMemberList) {
PutFieldN(level);
PutFieldN(banker);
PutFieldN(class_);
PutFieldN(rank);
/* Translate older ranks to new values */
switch (emu_e->rank) {
case 0: { e->rank = htonl(5); break; } // GUILD_MEMBER 0
case 1: { e->rank = htonl(3); break; } // GUILD_OFFICER 1
case 2: { e->rank = htonl(1); break; } // GUILD_LEADER 2
default: { e->rank = htonl(emu_e->rank); break; } // GUILD_NONE
}
PutFieldN(time_last_on);
PutFieldN(tribute_enable);
e->unknown01 = 0;
@@ -3330,7 +3344,15 @@ ENCODE(OP_SetGuildRank)
ENCODE_LENGTH_EXACT(GuildSetRank_Struct);
SETUP_DIRECT_ENCODE(GuildSetRank_Struct, structs::GuildSetRank_Struct);
eq->GuildID = emu->Unknown00;
OUT(Rank);
/* Translate older ranks to new values */
switch (emu->Rank) {
case 0: { eq->Rank = 5; break; } // GUILD_MEMBER 0
case 1: { eq->Rank = 3; break; } // GUILD_OFFICER 1
case 2: { eq->Rank = 1; break; } // GUILD_LEADER 2
default: { eq->Rank = emu->Rank; break; }
}
memcpy(eq->MemberName, emu->MemberName, sizeof(eq->MemberName));
OUT(Banker);
eq->Unknown76 = 1;
@@ -4660,8 +4682,11 @@ DECODE(OP_AugmentItem) {
SETUP_DIRECT_DECODE(AugmentItem_Struct, structs::AugmentItem_Struct);
emu->container_slot = RoFToServerSlot(eq->container_slot);
//emu->augment_slot = eq->augment_slot;
emu->augment_slot = RoFToServerSlot(eq->augment_slot);
emu->container_index = eq->container_index;
emu->augment_index = eq->augment_index;
emu->dest_inst_id = eq->dest_inst_id;
emu->augment_action = eq->augment_action;
FINISH_DIRECT_DECODE();
}
@@ -5068,7 +5093,7 @@ char* SerializeItem(const ItemInst *inst, int16 slot_id_in, uint32 *length, uint
memset(&isbs, 0, sizeof(RoF::structs::ItemSecondaryBodyStruct));
isbs.augtype = item->AugType;
isbs.augdistiller = 0;
isbs.augdistiller = 65535;
isbs.augrestrict = item->AugRestrict;
+3 -3
View File
@@ -2519,10 +2519,10 @@ struct Stun_Struct { // 8 bytes total
struct AugmentItem_Struct {
/*00*/ uint32 dest_inst_id; // The unique serial number for the item instance that is being augmented
/*04*/ uint32 unknown04; // Seen 0
/*04*/ uint32 container_index; // Seen 0
/*08*/ ItemSlotStruct container_slot; // Slot of the item being augmented
/*20*/ uint32 unknown20; // Seen 0
/*24*/ ItemSlotStruct distiller_slot; // Slot of the distiller to use (if one applies)
/*20*/ uint32 augment_index; // Seen 0
/*24*/ ItemSlotStruct augment_slot; // Slot of the distiller to use (if one applies)
/*36*/ int32 augment_action; // Guessed - 0 = augment, 1 = remove with distiller, 3 = delete aug
/*36*/ //int32 augment_slot;
/*40*/
+3 -3
View File
@@ -522,7 +522,7 @@ void Database::ExpireMail() {
query = StringFormat("DELETE FROM `mail` WHERE `status`=4 AND `timestamp` < %i",
time(nullptr) - RuleI(Mail, ExpireTrash));
results = QueryDatabase(query);
if(!results.Success())
if(results.Success())
_log(UCS__ERROR, "Error expiring trash messages, %s %s", query.c_str(), results.ErrorMessage().c_str());
else
_log(UCS__INIT, "Expired %i trash messages.", results.RowsAffected());
@@ -534,7 +534,7 @@ void Database::ExpireMail() {
query = StringFormat("DELETE FROM `mail` WHERE `status` = 3 AND `timestamp` < %i",
time(nullptr) - RuleI(Mail, ExpireRead));
results = QueryDatabase(query);
if(!results.Success())
if(results.Success())
_log(UCS__INIT, "Expired %i read messages.", results.RowsAffected());
else
_log(UCS__ERROR, "Error expiring read messages, %s %s", query.c_str(), results.ErrorMessage().c_str());
@@ -545,7 +545,7 @@ void Database::ExpireMail() {
query = StringFormat("DELETE FROM `mail` WHERE `status`=1 AND `timestamp` < %i",
time(nullptr) - RuleI(Mail, ExpireUnread));
results = QueryDatabase(query);
if(!results.Success())
if(results.Success())
_log(UCS__INIT, "Expired %i unread messages.", results.RowsAffected());
else
_log(UCS__ERROR, "Error expiring unread messages, %s %s", query.c_str(), results.ErrorMessage().c_str());
+1
View File
@@ -125,6 +125,7 @@ OP_GuildLeader=0x7c6f
OP_GuildDelete=0x241b
OP_GuildInviteAccept=0x78a5
OP_GuildDemote=0x3100
OP_GuildPromote=0x2945
OP_GuildPublicNote=0x3c2c
OP_GuildManageBanker=0x096d # Was 0x0737
OP_GuildBank=0x2ab0 # Was 0x10c3
+11 -11
View File
@@ -23,8 +23,8 @@ VERBOSE = False # messaging: {False - minimal, True - robust}
base_path = os.getcwd()[:-14] # '/utils/scripts'
base_path = base_path.replace('\\', '/')
client_list = ['6.2', 'Titanium', 'SoF', 'SoD', 'Underfoot', 'RoF', 'RoF2', 'ClientTest']
server_list = ['Login', 'World', 'Zone', 'UCS', 'ServerTest']
client_list = ['6.2', 'Titanium', 'SoF', 'SoD', 'Underfoot', 'RoF', 'RoF2']
server_list = ['Login', 'World', 'Zone', 'UCS']
client_opcodes = {} # x[key='Client'][key='OP_CodeName'](value='0x####')
server_opcodes = {} # x[key='OP_CodeName'](value=<integer>) - opcodes apply to all servers
@@ -248,7 +248,7 @@ def loadclientopcodes():
for client in client_list:
try:
short_name = '/patch_{0}.conf'.format(client)
short_name = '/patch_{0}.conf'.format(client).lower()
file_name = '{0}/utils/patches{1}'.format(
base_path,
@@ -455,9 +455,9 @@ def loadclienttranslators():
for client in client_list:
try:
if client == '6.2':
short_name = '/Client62_ops.h'
short_name = '/client62_ops.h'
else:
short_name = '/{0}_ops.h'.format(client)
short_name = '/{0}_ops.h'.format(client).lower()
file_name = '{0}/common/patches{1}'.format(
base_path,
@@ -734,15 +734,15 @@ def discoverserverhandlers():
locations[server] = []
if 'Login' in locations:
locations['Login'].append('/loginserver/Client.cpp')
locations['Login'].append('/loginserver/ServerManager.cpp')
locations['Login'].append('/loginserver/WorldServer.cpp')
locations['Login'].append('/loginserver/client.cpp')
locations['Login'].append('/loginserver/server_manager.cpp')
locations['Login'].append('/loginserver/world_server.cpp')
if 'World' in locations:
locations['World'].append('/world/client.cpp')
if 'Zone' in locations:
locations['Zone'].append('/zone/AA.cpp')
locations['Zone'].append('/zone/aa.cpp')
locations['Zone'].append('/zone/attack.cpp')
locations['Zone'].append('/zone/bot.cpp')
locations['Zone'].append('/zone/client.cpp')
@@ -762,8 +762,8 @@ def discoverserverhandlers():
locations['Zone'].append('/zone/loottables.cpp')
locations['Zone'].append('/zone/merc.cpp')
locations['Zone'].append('/zone/mob.cpp')
locations['Zone'].append('/zone/MobAI.cpp')
locations['Zone'].append('/zone/Object.cpp')
locations['Zone'].append('/zone/mob_ai.cpp')
locations['Zone'].append('/zone/object.cpp')
locations['Zone'].append('/zone/pathing.cpp')
locations['Zone'].append('/zone/petitions.cpp')
locations['Zone'].append('/zone/questmgr.cpp')
+1 -1
View File
@@ -715,7 +715,7 @@ bool AdventureManager::LoadAdventureEntries()
std::list<AdventureTemplate*> temp;
auto iter = adventure_entries.find(id);
if(iter == adventure_entries.end())
if(iter != adventure_entries.end())
temp = adventure_entries[id];
temp.push_back(tid);
-2
View File
@@ -11741,8 +11741,6 @@ void Bot::ProcessBotCommands(Client *c, const Seperator *sep) {
if(!strcasecmp(sep->arg[1], "augmentitem")) {
AugmentItem_Struct* in_augment = new AugmentItem_Struct[sizeof(AugmentItem_Struct)];
in_augment->container_slot = 1000; // <watch>
in_augment->unknown02[0] = 0;
in_augment->unknown02[1] = 0;
in_augment->augment_slot = -1;
Object::HandleAugmentation(c, in_augment, c->GetTradeskillObject());
return;
+12
View File
@@ -8334,3 +8334,15 @@ void Client::ExpeditionSay(const char *str, int ExpID) {
mysql_free_result(result);
}
void Client::ShowNumHits()
{
uint32 buffcount = GetMaxTotalSlots();
for (uint32 buffslot = 0; buffslot < buffcount; buffslot++) {
const Buffs_Struct &curbuff = buffs[buffslot];
if (curbuff.spellid != SPELL_UNKNOWN && curbuff.numhits)
Message(0, "You have %d hits left on %s", curbuff.numhits, GetSpellName(curbuff.spellid));
}
return;
}
+3 -1
View File
@@ -1200,7 +1200,9 @@ public:
void SetEngagedRaidTarget(bool value) { EngagedRaidTarget = value; }
bool GetEngagedRaidTarget() const { return EngagedRaidTarget; }
void ShowNumHits(); // work around function for numhits not showing on buffs
protected:
friend class Mob;
void CalcItemBonuses(StatBonuses* newbon);
+227 -8
View File
@@ -190,6 +190,7 @@ void MapOpcodes() {
ConnectedOpcodes[OP_GuildWar] = &Client::Handle_OP_GuildWar;
ConnectedOpcodes[OP_GuildLeader] = &Client::Handle_OP_GuildLeader;
ConnectedOpcodes[OP_GuildDemote] = &Client::Handle_OP_GuildDemote;
ConnectedOpcodes[OP_GuildPromote] = &Client::Handle_OP_GuildPromote;
ConnectedOpcodes[OP_GuildInvite] = &Client::Handle_OP_GuildInvite;
ConnectedOpcodes[OP_GuildRemove] = &Client::Handle_OP_GuildRemove;
ConnectedOpcodes[OP_GetGuildMOTD] = &Client::Handle_OP_GetGuildMOTD;
@@ -4088,7 +4089,7 @@ void Client::Handle_OP_GuildLeader(const EQApplicationPacket *app)
GuildMakeLeader* gml=(GuildMakeLeader*)app->pBuffer;
if (!IsInAGuild())
Message(0, "Error: You arent in a guild!");
else if (!guild_mgr.IsGuildLeader(GuildID(), CharacterID()))
else if (GuildRank() != GUILD_LEADER)
Message(0, "Error: You arent the guild leader!");
else if (!worldserver.Connected())
Message(0, "Error: World server disconnected");
@@ -4169,6 +4170,57 @@ void Client::Handle_OP_GuildDemote(const EQApplicationPacket *app)
return;
}
void Client::Handle_OP_GuildPromote(const EQApplicationPacket *app)
{
mlog(GUILDS__IN_PACKETS, "Received OP_GuildPromote");
mpkt(GUILDS__IN_PACKET_TRACE, app);
if(app->size != sizeof(GuildPromoteStruct)) {
mlog(GUILDS__ERROR, "Error: app size of %i != size of GuildDemoteStruct of %i\n",app->size,sizeof(GuildPromoteStruct));
return;
}
if (!IsInAGuild())
Message(0, "Error: You arent in a guild!");
else if (!guild_mgr.CheckPermission(GuildID(), GuildRank(), GUILD_PROMOTE))
Message(0, "You dont have permission to invite.");
else if (!worldserver.Connected())
Message(0, "Error: World server disconnected");
else {
GuildPromoteStruct* promote = (GuildPromoteStruct*)app->pBuffer;
CharGuildInfo gci;
if(!guild_mgr.GetCharInfo(promote->target, gci)) {
Message(0, "Unable to find '%s'", promote->target);
return;
}
if(gci.guild_id != GuildID()) {
Message(0, "You aren't in the same guild, what do you think you are doing?");
return;
}
uint8 rank = gci.rank + 1;
if(rank > GUILD_OFFICER)
return;
mlog(GUILDS__ACTIONS, "Promoting %s (%d) from rank %s (%d) to %s (%d) in %s (%d)",
promote->target, gci.char_id,
guild_mgr.GetRankName(GuildID(), gci.rank), gci.rank,
guild_mgr.GetRankName(GuildID(), rank), rank,
guild_mgr.GetGuildName(GuildID()), GuildID());
if(!guild_mgr.SetGuildRank(gci.char_id, rank)) {
Message(13, "Error while setting rank %d on '%s'.", rank, promote->target);
return;
}
Message(0, "Successfully promoted %s to rank %d", promote->target, rank);
}
return;
}
void Client::Handle_OP_GuildInvite(const EQApplicationPacket *app)
{
mlog(GUILDS__IN_PACKETS, "Received OP_GuildInvite");
@@ -4379,6 +4431,16 @@ void Client::Handle_OP_GuildInviteAccept(const EQApplicationPacket *app)
GuildInviteAccept_Struct* gj = (GuildInviteAccept_Struct*) app->pBuffer;
if(GetClientVersion() >= EQClientRoF)
{
if(gj->response > 9)
{
//dont care if the check fails (since we dont know the rank), just want to clear the entry.
guild_mgr.VerifyAndClearInvite(CharacterID(), gj->guildeqid, gj->response);
worldserver.SendEmoteMessage(gj->inviter, 0, 0, "%s has declined to join the guild.", this->GetName());
return;
}
}
if (gj->response == 5 || gj->response == 4) {
//dont care if the check fails (since we dont know the rank), just want to clear the entry.
guild_mgr.VerifyAndClearInvite(CharacterID(), gj->guildeqid, gj->response);
@@ -4424,15 +4486,24 @@ void Client::Handle_OP_GuildInviteAccept(const EQApplicationPacket *app)
guild_mgr.GetGuildName(gj->guildeqid), gj->guildeqid,
gj->response);
//change guild and rank.
if(!guild_mgr.SetGuild(CharacterID(), gj->guildeqid, gj->response)) {
//change guild and rank
uint32 guildrank = gj->response;
if(GetClientVersion() == EQClientRoF)
{
if(gj->response == 8)
{
guildrank = 0;
}
}
if(!guild_mgr.SetGuild(CharacterID(), gj->guildeqid, guildrank)) {
Message(13, "There was an error during the invite, DB may now be inconsistent.");
return;
}
if(zone->GetZoneID() == RuleI(World, GuildBankZoneID) && GuildBanks)
GuildBanks->SendGuildBank(this);
SendGuildRanks();
}
}
}
@@ -6210,7 +6281,145 @@ void Client::Handle_OP_AugmentItem(const EQApplicationPacket *app)
// Delegate to tradeskill object to perform combine
AugmentItem_Struct* in_augment = (AugmentItem_Struct*)app->pBuffer;
Object::HandleAugmentation(this, in_augment, m_tradeskill_object);
bool deleteItems = false;
if(GetClientVersion() >= EQClientRoF)
{
ItemInst *itemOneToPush = nullptr, *itemTwoToPush = nullptr;
//Message(15, "%i %i %i %i %i %i", in_augment->container_slot, in_augment->augment_slot, in_augment->container_index, in_augment->augment_index, in_augment->augment_action, in_augment->dest_inst_id);
// Adding augment
if (in_augment->augment_action == 0)
{
ItemInst *tobe_auged, *auged_with = nullptr;
int8 slot=-1;
Inventory& user_inv = GetInv();
uint16 slot_id = in_augment->container_slot;
uint16 aug_slot_id = in_augment->augment_slot;
//Message(13, "%i AugSlot", aug_slot_id);
if(slot_id == INVALID_INDEX || aug_slot_id == INVALID_INDEX)
{
Message(13, "Error: Invalid Aug Index.");
return;
}
tobe_auged = user_inv.GetItem(slot_id);
auged_with = user_inv.GetItem(MainCursor);
if(tobe_auged && auged_with)
{
if (((slot=tobe_auged->AvailableAugmentSlot(auged_with->GetAugmentType()))!=-1) &&
(tobe_auged->AvailableWearSlot(auged_with->GetItem()->Slots)))
{
tobe_auged->PutAugment(slot, *auged_with);
ItemInst *aug = tobe_auged->GetAugment(in_augment->augment_index);
if(aug) {
std::vector<EQEmu::Any> args;
args.push_back(aug);
parse->EventItem(EVENT_AUGMENT_ITEM, this, tobe_auged, nullptr, "", in_augment->augment_index, &args);
args.assign(1, tobe_auged);
parse->EventItem(EVENT_AUGMENT_INSERT, this, aug, nullptr, "", in_augment->augment_index, &args);
}
else
{
Message(13, "Error: Could not find augmentation at index %i. Aborting.");
return;
}
itemOneToPush = tobe_auged->Clone();
// Must push items after the items in inventory are deleted - necessary due to lore items...
if (itemOneToPush)
{
DeleteItemInInventory(slot_id, 0, true);
DeleteItemInInventory(MainCursor, 0, true);
if(PutItemInInventory(slot_id, *itemOneToPush, true))
{
//Message(13, "Sucessfully added an augment to your item!");
return;
}
else
{
Message(13, "Error: No available slot for end result. Please free up some bag space.");
}
}
else
{
Message(13, "Error in cloning item for augment. Aborted.");
}
}
else
{
Message(13, "Error: No available slot for augment in that item.");
}
}
}
else if(in_augment->augment_action == 1)
{
ItemInst *tobe_auged, *auged_with = nullptr;
int8 slot=-1;
Inventory& user_inv = GetInv();
uint16 slot_id = in_augment->container_slot;
uint16 aug_slot_id = in_augment->augment_slot; //it's actually solvent slot
if(slot_id == INVALID_INDEX || aug_slot_id == INVALID_INDEX)
{
Message(13, "Error: Invalid Aug Index.");
return;
}
tobe_auged = user_inv.GetItem(slot_id);
auged_with = user_inv.GetItem(aug_slot_id);
ItemInst *old_aug = nullptr;
if(!auged_with)
return;
const uint32 id = auged_with->GetID();
ItemInst *aug = tobe_auged->GetAugment(in_augment->augment_index);
if(aug) {
std::vector<EQEmu::Any> args;
args.push_back(aug);
parse->EventItem(EVENT_UNAUGMENT_ITEM, this, tobe_auged, nullptr, "", in_augment->augment_index, &args);
args.assign(1, tobe_auged);
args.push_back(false);
parse->EventItem(EVENT_AUGMENT_REMOVE, this, aug, nullptr, "", in_augment->augment_index, &args);
}
else
{
Message(13, "Error: Could not find augmentation at index %i. Aborting.");
return;
}
old_aug = tobe_auged->RemoveAugment(in_augment->augment_index);
itemOneToPush = tobe_auged->Clone();
if (old_aug)
itemTwoToPush = old_aug->Clone();
if(itemOneToPush && itemTwoToPush && auged_with)
{
DeleteItemInInventory(slot_id, 0, true);
DeleteItemInInventory(aug_slot_id, auged_with->IsStackable() ? 1 : 0, true);
if(!PutItemInInventory(slot_id, *itemOneToPush, true))
{
Message(15, "Shouldn't happen, contact an admin!");
}
if(PutItemInInventory(MainCursor, *itemTwoToPush, true))
{
//Message(15, "Successfully removed an augmentation!");
}
}
}
}
else
{
Object::HandleAugmentation(this, in_augment, m_tradeskill_object);
}
return;
}
@@ -6225,7 +6434,7 @@ void Client::Handle_OP_ClickDoor(const EQApplicationPacket *app)
if(!currentdoor)
{
Message(0,"Unable to find door, please notify a GM (DoorID: %i).",cd->doorid);
return;
return;
}
char buf[20];
@@ -9301,8 +9510,18 @@ void Client::CompleteConnect() {
UpdateAdmin(false);
if (IsInAGuild()){
uint8 rank = GuildRank();
if(GetClientVersion() >= EQClientRoF)
{
switch (rank) {
case 0: { rank = 5; break; } // GUILD_MEMBER 0
case 1: { rank = 3; break; } // GUILD_OFFICER 1
case 2: { rank = 1; break; } // GUILD_LEADER 2
default: { break; } // GUILD_NONE
}
}
SendAppearancePacket(AT_GuildID, GuildID(), false);
SendAppearancePacket(AT_GuildRank, GuildRank(), false);
SendAppearancePacket(AT_GuildRank, rank, false);
}
for (uint32 spellInt = 0; spellInt < MAX_PP_SPELLBOOK; spellInt++)
{
+1
View File
@@ -90,6 +90,7 @@
void Handle_OP_GuildWar(const EQApplicationPacket *app);
void Handle_OP_GuildLeader(const EQApplicationPacket *app);
void Handle_OP_GuildDemote(const EQApplicationPacket *app);
void Handle_OP_GuildPromote(const EQApplicationPacket *app);
void Handle_OP_GuildInvite(const EQApplicationPacket *app);
void Handle_OP_GuildRemove(const EQApplicationPacket *app);
void Handle_OP_GetGuildMOTD(const EQApplicationPacket *app);
+9 -4
View File
@@ -453,7 +453,8 @@ int command_init(void) {
command_add("merchant_open_shop", "Opens a merchants shop", 100, command_merchantopenshop) ||
command_add("open_shop", nullptr, 100, command_merchantopenshop) ||
command_add("merchant_close_shop", "Closes a merchant shop", 100, command_merchantcloseshop) ||
command_add("close_shop", nullptr, 100, command_merchantcloseshop)
command_add("close_shop", nullptr, 100, command_merchantcloseshop) ||
command_add("shownumhits", "Shows buffs numhits for yourself.", 0, command_shownumhits)
)
{
command_deinit();
@@ -4692,7 +4693,7 @@ void command_loc(Client *c, const Seperator *sep)
{
Mob *t=c->GetTarget()?c->GetTarget():c->CastToMob();
c->Message(0, "%s's Location (XYZ): %1.1f, %1.1f, %1.1f; heading=%1.1f", t->GetName(), t->GetX(), t->GetY(), t->GetZ(), t->GetHeading());
c->Message(0, "%s's Location (XYZ): %1.2f, %1.2f, %1.2f; heading=%1.1f", t->GetName(), t->GetX(), t->GetY(), t->GetZ(), t->GetHeading());
}
void command_goto(Client *c, const Seperator *sep)
@@ -11429,8 +11430,6 @@ void command_augmentitem(Client *c, const Seperator *sep)
AugmentItem_Struct* in_augment = new AugmentItem_Struct[sizeof(AugmentItem_Struct)];
in_augment->container_slot = 1000; // <watch>
in_augment->unknown02[0] = 0;
in_augment->unknown02[1] = 0;
in_augment->augment_slot = -1;
if(c->GetTradeskillObject() != nullptr)
Object::HandleAugmentation(c, in_augment, c->GetTradeskillObject());
@@ -11557,3 +11556,9 @@ void command_merchantcloseshop(Client *c, const Seperator *sep)
merchant->CastToNPC()->MerchantCloseShop();
}
void command_shownumhits(Client *c, const Seperator *sep)
{
c->ShowNumHits();
return;
}
+1
View File
@@ -325,6 +325,7 @@ void command_showspellslist(Client *c, const Seperator *sep);
void command_npctype_cache(Client *c, const Seperator *sep);
void command_merchantopenshop(Client *c, const Seperator *sep);
void command_merchantcloseshop(Client *c, const Seperator *sep);
void command_shownumhits(Client *c, const Seperator *sep);
#ifdef EQPROFILE
void command_profiledump(Client *c, const Seperator *sep);
+3 -1
View File
@@ -1130,8 +1130,10 @@ void PerlembParser::ExportEventVariables(std::string &package_name, QuestEventID
case EVENT_TRADE: {
if(extra_pointers) {
for(size_t i = 0; i < extra_pointers->size(); ++i) {
size_t sz = extra_pointers->size();
for(size_t i = 0; i < sz; ++i) {
ItemInst *inst = EQEmu::any_cast<ItemInst*>(extra_pointers->at(i));
std::string var_name = "item";
var_name += std::to_string(static_cast<long long>(i + 1));
+2 -1
View File
@@ -3242,7 +3242,8 @@ void EntityList::ProcessMove(Client *c, float x, float y, float z)
for (auto iter = events.begin(); iter != events.end(); ++iter) {
quest_proximity_event& evt = (*iter);
if (evt.npc) {
parse->EventNPC(evt.event_id, evt.npc, evt.client, "", 0);
std::vector<EQEmu::Any> args;
parse->EventNPC(evt.event_id, evt.npc, evt.client, "", 0, &args);
} else {
std::vector<EQEmu::Any> args;
args.push_back(&evt.area_id);
+9 -9
View File
@@ -235,7 +235,7 @@ bool Client::CanFish() {
dest.y = RodY;
dest.z = z_pos+10;
RodZ = zone->zonemap->FindBestZ(dest, nullptr) - 1;
RodZ = zone->zonemap->FindBestZ(dest, nullptr) + 4;
bool in_lava = zone->watermap->InLava(RodX, RodY, RodZ);
bool in_water = zone->watermap->InWater(RodX, RodY, RodZ) || zone->watermap->InVWater(RodX, RodY, RodZ);
//Message(0, "Rod is at %4.3f, %4.3f, %4.3f, InWater says %d, InLava says %d", RodX, RodY, RodZ, in_water, in_lava);
@@ -355,11 +355,11 @@ void Client::GoFish()
safe_delete(inst);
inst = m_inv.GetItem(MainCursor);
}
}
std::vector<EQEmu::Any> args;
args.push_back(inst);
parse->EventPlayer(EVENT_FISH_SUCCESS, this, "", inst != nullptr ? inst->GetItem()->ID : 0, &args);
std::vector<EQEmu::Any> args;
args.push_back(inst);
parse->EventPlayer(EVENT_FISH_SUCCESS, this, "", inst->GetID(), &args);
}
}
else
{
@@ -469,11 +469,11 @@ void Client::ForageItem(bool guarantee) {
safe_delete(inst);
inst = m_inv.GetItem(MainCursor);
}
}
std::vector<EQEmu::Any> args;
args.push_back(inst);
parse->EventPlayer(EVENT_FORAGE_SUCCESS, this, "", inst ? inst->GetItem()->ID : 0, &args);
std::vector<EQEmu::Any> args;
args.push_back(inst);
parse->EventPlayer(EVENT_FORAGE_SUCCESS, this, "", inst->GetID(), &args);
}
int ChanceSecondForage = aabonuses.ForageAdditionalItems + itembonuses.ForageAdditionalItems + spellbonuses.ForageAdditionalItems;
if(!guarantee && MakeRandomInt(0,99) < ChanceSecondForage) {
+9 -1
View File
@@ -160,9 +160,17 @@ void Client::SendGuildSpawnAppearance() {
uint8 rank = guild_mgr.GetDisplayedRank(GuildID(), GuildRank(), CharacterID());
mlog(GUILDS__OUT_PACKETS, "Sending spawn appearance for guild %d at rank %d", GuildID(), rank);
SendAppearancePacket(AT_GuildID, GuildID());
if(GetClientVersion() >= EQClientRoF)
{
switch (rank) {
case 0: { rank = 5; break; } // GUILD_MEMBER 0
case 1: { rank = 3; break; } // GUILD_OFFICER 1
case 2: { rank = 1; break; } // GUILD_LEADER 2
default: { break; } // GUILD_NONE
}
}
SendAppearancePacket(AT_GuildRank, rank);
}
UpdateWho();
}
+19 -8
View File
@@ -374,6 +374,10 @@ void ZoneGuildManager::ProcessWorldPacket(ServerPacket *pack) {
else if(c != nullptr && s->guild_id != GUILD_NONE) {
//char is in zone, and has changed into a new guild, send MOTD.
c->SendGuildMOTD();
if(c->GetClientVersion() >= EQClientRoF)
{
c->SendGuildRanks();
}
}
@@ -686,19 +690,26 @@ bool GuildBankManager::Load(uint32 guildID)
else
whoFor[0] = '\0';
if(slot < 0 ||
((area != GuildBankMainArea || slot >= GUILD_BANK_MAIN_AREA_SIZE) ||
(area == GuildBankMainArea || slot >= GUILD_BANK_DEPOSIT_AREA_SIZE)))
if(slot < 0)
continue;
bank->Items.MainArea[slot].ItemID = itemID;
bank->Items.MainArea[slot].Quantity = qty;
GuildBankItem *itemSection = nullptr;
strn0cpy(bank->Items.MainArea[slot].Donator, donator, sizeof(donator));
if (area == GuildBankMainArea && slot < GUILD_BANK_MAIN_AREA_SIZE)
itemSection = bank->Items.MainArea;
else if (area != GuildBankMainArea && slot < GUILD_BANK_DEPOSIT_AREA_SIZE)
itemSection = bank->Items.DepositArea;
else
continue;
bank->Items.MainArea[slot].Permissions = permissions;
itemSection[slot].ItemID = itemID;
itemSection[slot].Quantity = qty;
strn0cpy(bank->Items.MainArea[slot].WhoFor, whoFor, sizeof(whoFor));
strn0cpy(itemSection[slot].Donator, donator, sizeof(donator));
itemSection[slot].Permissions = permissions;
strn0cpy(itemSection[slot].WhoFor, whoFor, sizeof(whoFor));
}
Banks.push_back(bank);
+1 -1
View File
@@ -163,7 +163,7 @@ Mob* HateList::GetClosest(Mob *hater) {
++iterator;
}
if (close == 0 && hater->IsNPC() || close->DivineAura())
if ((!close && hater->IsNPC()) || (close && close->DivineAura()))
close = hater->CastToNPC()->GetHateTop();
return close;
+7 -1
View File
@@ -416,6 +416,11 @@ void Lua_EntityList::SignalAllClients(int signal) {
self->SignalAllClients(signal);
}
void Lua_EntityList::ChannelMessage(Lua_Mob from, int channel_num, int language, const char *message) {
Lua_Safe_Call_Void();
self->ChannelMessage(from, channel_num, language, message);
}
luabind::scope lua_register_entity_list() {
return luabind::class_<Lua_EntityList>("EntityList")
.def(luabind::constructor<>())
@@ -479,7 +484,8 @@ luabind::scope lua_register_entity_list() {
.def("GetObjectList", (Lua_Object_List(Lua_EntityList::*)(void))&Lua_EntityList::GetObjectList)
.def("GetDoorsList", (Lua_Doors_List(Lua_EntityList::*)(void))&Lua_EntityList::GetDoorsList)
.def("GetSpawnList", (Lua_Spawn_List(Lua_EntityList::*)(void))&Lua_EntityList::GetSpawnList)
.def("SignalAllClients", (void(Lua_EntityList::*)(int))&Lua_EntityList::SignalAllClients);
.def("SignalAllClients", (void(Lua_EntityList::*)(int))&Lua_EntityList::SignalAllClients)
.def("ChannelMessage", (void(Lua_EntityList::*)(Lua_Mob,int,int,const char*))&Lua_EntityList::ChannelMessage);
}
luabind::scope lua_register_mob_list() {
+1
View File
@@ -106,6 +106,7 @@ public:
Lua_Doors_List GetDoorsList();
Lua_Spawn_List GetSpawnList();
void SignalAllClients(int signal);
void ChannelMessage(Lua_Mob from, int channel_num, int language, const char *message);
};
#endif
+1 -7
View File
@@ -1451,11 +1451,7 @@ luabind::scope lua_register_slot() {
luabind::value("General6", static_cast<int>(MainGeneral6)),
luabind::value("General7", static_cast<int>(MainGeneral7)),
luabind::value("General8", static_cast<int>(MainGeneral8)),
//luabind::value("General9", static_cast<int>(MainGeneral9)),
//luabind::value("General10", static_cast<int>(MainGeneral10)),
luabind::value("Cursor", static_cast<int>(MainCursor)),
//luabind::value("EquipmentBegin", static_cast<int>(EmuConstants::EQUIPMENT_BEGIN)),
//luabind::value("EquipmentEnd", static_cast<int>(EmuConstants::EQUIPMENT_END)),
luabind::value("PersonalBegin", static_cast<int>(EmuConstants::GENERAL_BEGIN)), // deprecated
luabind::value("GeneralBegin", static_cast<int>(EmuConstants::GENERAL_BEGIN)),
luabind::value("PersonalEnd", static_cast<int>(EmuConstants::GENERAL_END)), // deprecated
@@ -1483,7 +1479,6 @@ luabind::scope lua_register_material() {
luabind::value("Secondary", static_cast<int>(MaterialSecondary)),
luabind::value("Max", static_cast<int>(_MaterialCount)), // deprecated
luabind::value("Count", static_cast<int>(_MaterialCount)),
//luabind::value("TintCount", static_cast<int>(_MaterialCount - 2)),
luabind::value("Invalid", static_cast<int>(_MaterialInvalid))
];
}
@@ -1498,8 +1493,7 @@ luabind::scope lua_register_client_version() {
luabind::value("SoF", static_cast<int>(EQClientSoF)),
luabind::value("SoD", static_cast<int>(EQClientSoD)),
luabind::value("Underfoot", static_cast<int>(EQClientUnderfoot)),
luabind::value("RoF", static_cast<int>(EQClientRoF))//,
//luabind::value("RoF2", static_cast<int>(EQClientRoF2))
luabind::value("RoF", static_cast<int>(EQClientRoF))
];
}
+5 -2
View File
@@ -54,9 +54,12 @@ void handle_npc_event_trade(QuestInterface *parse, lua_State* L, NPC* npc, Mob *
ident << npc->GetNPCTypeID();
if(extra_pointers) {
for(size_t i = 0; i < extra_pointers->size(); ++i) {
size_t sz = extra_pointers->size();
for(size_t i = 0; i < sz; ++i) {
std::string prefix = "item" + std::to_string(static_cast<long long>(i + 1));
Lua_ItemInst l_inst = EQEmu::any_cast<ItemInst*>(extra_pointers->at(i));
ItemInst *inst = EQEmu::any_cast<ItemInst*>(extra_pointers->at(i));
Lua_ItemInst l_inst = inst;
luabind::adl::object l_inst_o = luabind::adl::object(L, l_inst);
l_inst_o.push(L);
+1
View File
@@ -727,6 +727,7 @@ public:
virtual void AI_Init();
virtual void AI_Start(uint32 iMoveDelay = 0);
virtual void AI_Stop();
virtual void AI_ShutDown();
virtual void AI_Process();
const char* GetEntityVariable(const char *id);
+28 -24
View File
@@ -550,30 +550,6 @@ void Mob::AI_Stop() {
safe_delete(AItarget_check_timer);
safe_delete(AIscanarea_timer);
safe_delete(AIfeignremember_timer);
safe_delete(PathingLOSCheckTimer);
safe_delete(PathingRouteUpdateTimerShort);
safe_delete(PathingRouteUpdateTimerLong);
attack_timer.Disable();
attack_dw_timer.Disable();
ranged_timer.Disable();
tic_timer.Disable();
mana_timer.Disable();
spellend_timer.Disable();
projectile_timer.Disable();
rewind_timer.Disable();
bindwound_timer.Disable();
stunned_timer.Disable();
spun_timer.Disable();
bardsong_timer.Disable();
gravity_timer.Disable();
viral_timer.Disable();
flee_timer.Disable();
for (int sat = 0; sat < MAX_SPECIAL_ATTACK; ++sat) {
if (SpecialAbilities[sat].timer)
SpecialAbilities[sat].timer->Disable();
}
hate_list.Wipe();
}
@@ -609,6 +585,34 @@ void Client::AI_Stop() {
}
}
// only call this on a zone shutdown event
void Mob::AI_ShutDown() {
safe_delete(PathingLOSCheckTimer);
safe_delete(PathingRouteUpdateTimerShort);
safe_delete(PathingRouteUpdateTimerLong);
attack_timer.Disable();
attack_dw_timer.Disable();
ranged_timer.Disable();
tic_timer.Disable();
mana_timer.Disable();
spellend_timer.Disable();
projectile_timer.Disable();
rewind_timer.Disable();
bindwound_timer.Disable();
stunned_timer.Disable();
spun_timer.Disable();
bardsong_timer.Disable();
gravity_timer.Disable();
viral_timer.Disable();
flee_timer.Disable();
for (int sat = 0; sat < MAX_SPECIAL_ATTACK; ++sat) {
if (SpecialAbilities[sat].timer)
SpecialAbilities[sat].timer->Disable();
}
}
//todo: expand the logic here to cover:
//redundant debuffs
//buffing owner
+1 -1
View File
@@ -871,7 +871,7 @@ void Client::FinishTrade(Mob* tradingWith, bool finalizer, void* event_entry, st
items[i - EmuConstants::TRADE_BEGIN] = inst->GetItem()->ID;
item_list.push_back(inst);
} else {
item_list.push_back(nullptr);
item_list.push_back((ItemInst*)nullptr);
continue;
}
+4 -1
View File
@@ -594,15 +594,17 @@ void Zone::LoadMercTemplates(){
tempMercTemplate.Stances[i] = 0;
int stanceIndex = 0;
for (std::list<MercStanceInfo>::iterator mercStanceListItr = merc_stances.begin(); mercStanceListItr != merc_stances.end(); ++mercStanceListItr, ++stanceIndex) {
for (auto mercStanceListItr = merc_stances.begin(); mercStanceListItr != merc_stances.end(); ++mercStanceListItr) {
if(mercStanceListItr->ClassID != tempMercTemplate.ClassID || mercStanceListItr->ProficiencyID != tempMercTemplate.ProficiencyID)
continue;
zone->merc_stance_list[tempMercTemplate.MercTemplateID].push_back((*mercStanceListItr));
tempMercTemplate.Stances[stanceIndex] = mercStanceListItr->StanceID;
++stanceIndex;
}
merc_templates[tempMercTemplate.MercTemplateID] = tempMercTemplate;
}
}
@@ -733,6 +735,7 @@ void Zone::Shutdown(bool quite)
while (mob_itr != mob_list.end()) {
Mob* mob_inst = *mob_itr;
mob_inst->AI_Stop();
mob_inst->AI_ShutDown();
++mob_itr;
}