mirror of
https://github.com/EQEmu/Server.git
synced 2026-09-02 12:36:36 +00:00
Moved merc save data from extended player profile to new merc table, save merc buffs, added cure and rez spells to healer merc.
This commit is contained in:
+17
-10
@@ -258,6 +258,8 @@ Client::Client(EQStreamInterface* ieqs)
|
||||
keyring.clear();
|
||||
bind_sight_target = NULL;
|
||||
mercid = 0;
|
||||
mercSlot = 0;
|
||||
InitializeMercInfo();
|
||||
SetMerc(0);
|
||||
|
||||
logging_enabled = CLIENT_DEFAULT_LOGGING_ENABLED;
|
||||
@@ -557,12 +559,17 @@ bool Client::Save(uint8 iCommitNow) {
|
||||
m_pp.timePlayedMin = (TotalSecondsPlayed / 60);
|
||||
m_pp.RestTimer = rest_timer.GetRemainingTime() / 1000;
|
||||
|
||||
if(GetEPP().mercTimerRemaining > RuleI(Mercs, UpkeepIntervalMS))
|
||||
GetEPP().mercTimerRemaining = RuleI(Mercs, UpkeepIntervalMS);
|
||||
if(GetMercInfo().MercTimerRemaining > RuleI(Mercs, UpkeepIntervalMS))
|
||||
GetMercInfo().MercTimerRemaining = RuleI(Mercs, UpkeepIntervalMS);
|
||||
|
||||
if(merc_timer.Enabled())
|
||||
{
|
||||
GetEPP().mercTimerRemaining = merc_timer.GetRemainingTime();
|
||||
if(merc_timer.Enabled()) {
|
||||
GetMercInfo().MercTimerRemaining = merc_timer.GetRemainingTime();
|
||||
}
|
||||
|
||||
if (GetMerc() && !dead) {
|
||||
|
||||
} else {
|
||||
memset(&m_mercinfo, 0, sizeof(struct MercInfo));
|
||||
}
|
||||
|
||||
m_pp.lastlogin = time(NULL);
|
||||
@@ -7127,7 +7134,7 @@ void Client::SendMercPersonalInfo()
|
||||
{
|
||||
MercenaryDataUpdate_Struct* mdus = new MercenaryDataUpdate_Struct;
|
||||
|
||||
MercTemplate *mercData = &zone->merc_templates[GetEPP().mercTemplateID];
|
||||
MercTemplate *mercData = &zone->merc_templates[GetMercInfo().MercTemplateID];
|
||||
|
||||
if (mercData)
|
||||
{
|
||||
@@ -7146,13 +7153,13 @@ void Client::SendMercPersonalInfo()
|
||||
mdus->MercData[i].AltCurrencyUpkeep = Merc::CalcPurchaseCost(mercData->MercTemplateID, GetLevel(), altCurrentType);
|
||||
mdus->MercData[i].AltCurrencyType = altCurrentType;
|
||||
mdus->MercData[i].MercUnk01 = 0;
|
||||
mdus->MercData[i].TimeLeft = GetEPP().mercTimerRemaining; //GetMercTimer().GetRemainingTime();
|
||||
mdus->MercData[i].TimeLeft = GetMercInfo().MercTimerRemaining; //GetMercTimer().GetRemainingTime();
|
||||
mdus->MercData[i].MerchantSlot = i + 1;
|
||||
mdus->MercData[i].MercUnk02 = 1;
|
||||
mdus->MercData[i].StanceCount = zone->merc_stance_list[mercData->MercTemplateID].size();
|
||||
mdus->MercData[i].MercUnk03 = 0;
|
||||
mdus->MercData[i].MercUnk04 = 1;
|
||||
strn0cpy(mdus->MercData[i].MercName, GetEPP().merc_name , sizeof(mdus->MercData[i].MercName));
|
||||
strn0cpy(mdus->MercData[i].MercName, GetMercInfo().merc_name , sizeof(mdus->MercData[i].MercName));
|
||||
uint32 stanceindex = 0;
|
||||
if (mdus->MercData[i].StanceCount != 0)
|
||||
{
|
||||
@@ -7179,7 +7186,7 @@ void Client::SendMercPersonalInfo()
|
||||
else
|
||||
{
|
||||
MercenaryMerchantList_Struct* mml = new MercenaryMerchantList_Struct;
|
||||
MercTemplate *mercData = &zone->merc_templates[GetEPP().mercTemplateID];
|
||||
MercTemplate *mercData = &zone->merc_templates[GetMercInfo().MercTemplateID];
|
||||
|
||||
if(mercData)
|
||||
{
|
||||
@@ -7202,7 +7209,7 @@ void Client::SendMercPersonalInfo()
|
||||
mml->Mercs[i].AltCurrencyUpkeep = Merc::CalcPurchaseCost(mercData->MercTemplateID, GetLevel(), altCurrentType);
|
||||
mml->Mercs[i].AltCurrencyType = altCurrentType;
|
||||
mml->Mercs[i].MercUnk01 = 0;
|
||||
mml->Mercs[i].TimeLeft = GetEPP().mercTimerRemaining;
|
||||
mml->Mercs[i].TimeLeft = GetMercInfo().MercTimerRemaining;
|
||||
mml->Mercs[i].MerchantSlot = i + 1;
|
||||
mml->Mercs[i].MercUnk02 = 1;
|
||||
mml->Mercs[i].StanceCount = zone->merc_stance_list[mercData->MercTemplateID].size();
|
||||
|
||||
+10
-3
@@ -1095,9 +1095,15 @@ public:
|
||||
void SendXTargetPacket(uint32 Slot, Mob *m);
|
||||
void RemoveGroupXTargets();
|
||||
void ShowXTargets(Client *c);
|
||||
void InitializeMercInfo();
|
||||
inline uint32 GetMercID() const { return mercid; }
|
||||
inline uint8 GetMercSlot() const { return mercSlot; }
|
||||
void SetMercID( uint32 newmercid) { mercid = newmercid; }
|
||||
void SetMercSlot( uint8 newmercslot) { mercSlot = newmercslot; }
|
||||
Merc* GetMerc();
|
||||
MercInfo& GetMercInfo(uint8 slot) { return m_mercinfo[slot]; }
|
||||
MercInfo& GetMercInfo() { return m_mercinfo[mercSlot]; }
|
||||
uint8 GetNumMercs();
|
||||
void SetMerc(Merc* newmerc);
|
||||
void SendMercMerchantResponsePacket(int32 response_type);
|
||||
void SendMercenaryUnknownPacket(uint8 type);
|
||||
@@ -1109,7 +1115,7 @@ public:
|
||||
void SendClearMercInfo();
|
||||
void SuspendMercCommand();
|
||||
void SpawnMercOnZone();
|
||||
void SpawnMerc(Merc* merc);
|
||||
void SpawnMerc(Merc* merc, bool setMaxStats);
|
||||
void UpdateMercTimer();
|
||||
void UpdateMercLevel();
|
||||
void CheckMercSuspendTimer();
|
||||
@@ -1257,7 +1263,8 @@ private:
|
||||
uint16 CustomerID;
|
||||
uint32 account_creation;
|
||||
uint8 firstlogon;
|
||||
uint32 mercid;
|
||||
uint32 mercid; // current merc
|
||||
uint8 mercSlot; // selected merc slot
|
||||
bool Trader;
|
||||
bool Buyer;
|
||||
string BuyerWelcomeMessage;
|
||||
@@ -1273,7 +1280,7 @@ private:
|
||||
Object* m_tradeskill_object;
|
||||
PetInfo m_petinfo; // current pet data, used while loading from and saving to DB
|
||||
PetInfo m_suspendedminion; // pet data for our suspended minion.
|
||||
MercInfo m_mercinfo; // current mercenary
|
||||
MercInfo m_mercinfo[MAXMERCS]; // current mercenary
|
||||
InspectMessage_Struct m_inspect_message;
|
||||
|
||||
void NPCSpawn(const Seperator* sep);
|
||||
|
||||
@@ -13629,11 +13629,12 @@ void Client::Handle_OP_MercenaryHire(const EQApplicationPacket *app)
|
||||
SendMercMerchantResponsePacket(0);
|
||||
|
||||
// Set time remaining to max on Hire
|
||||
GetEPP().mercTimerRemaining = RuleI(Mercs, UpkeepIntervalMS);
|
||||
GetMercInfo().MercTimerRemaining = RuleI(Mercs, UpkeepIntervalMS);
|
||||
|
||||
// Get merc, assign it to client & spawn
|
||||
Merc* merc = Merc::LoadMerc(this, merc_template, merchant_id);
|
||||
SpawnMerc(merc);
|
||||
Merc* merc = Merc::LoadMerc(this, merc_template, merchant_id, false);
|
||||
SpawnMerc(merc, true);
|
||||
merc->Save();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13677,7 +13678,7 @@ void Client::Handle_OP_MercenaryCommand(const EQApplicationPacket *app)
|
||||
|
||||
if(option >= 0)
|
||||
{
|
||||
GetEPP().mercState = option;
|
||||
GetMercInfo().State = option;
|
||||
}
|
||||
|
||||
DumpPacket(app);
|
||||
@@ -13777,10 +13778,10 @@ void Client::Handle_OP_MercenaryTimerRequest(const EQApplicationPacket *app)
|
||||
|
||||
if(merc) {
|
||||
entityID = merc->GetID();
|
||||
|
||||
if(GetEPP().mercIsSuspended) {
|
||||
|
||||
if(GetMercInfo().IsSuspended) {
|
||||
mercState = 1;
|
||||
suspendedTime = GetEPP().mercSuspendedTime;
|
||||
suspendedTime = GetMercInfo().SuspendedTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -195,6 +195,7 @@ bool Client::Process() {
|
||||
LeaveGroup();
|
||||
if (GetMerc())
|
||||
{
|
||||
GetMerc()->Save();
|
||||
GetMerc()->RemoveMercFromGroup(GetMerc(), GetMerc()->GetGroup());
|
||||
GetMerc()->Depop();
|
||||
}
|
||||
@@ -211,6 +212,7 @@ bool Client::Process() {
|
||||
Save();
|
||||
if (GetMerc())
|
||||
{
|
||||
GetMerc()->Save();
|
||||
GetMerc()->RemoveMercFromGroup(GetMerc(), GetMerc()->GetGroup());
|
||||
GetMerc()->Depop();
|
||||
}
|
||||
@@ -251,7 +253,7 @@ bool Client::Process() {
|
||||
UpdateMercTimer();
|
||||
}
|
||||
|
||||
if(GetEPP().mercTemplateID != 0)
|
||||
if(GetMercInfo().MercTemplateID != 0)
|
||||
{
|
||||
if(p_timers.Expired(&database, pTimerMercSuspend, false)) {
|
||||
CheckMercSuspendTimer();
|
||||
@@ -679,6 +681,7 @@ bool Client::Process() {
|
||||
if (GetGM()) {
|
||||
if (GetMerc())
|
||||
{
|
||||
GetMerc()->Save();
|
||||
GetMerc()->RemoveMercFromGroup(GetMerc(), GetMerc()->GetGroup());
|
||||
GetMerc()->Depop();
|
||||
}
|
||||
|
||||
@@ -1987,6 +1987,24 @@ Corpse* EntityList::GetCorpseByOwner(Client* client){
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Corpse* EntityList::GetCorpseByOwnerWithinRange(Client* client, Mob* center, int range){
|
||||
LinkedListIterator<Corpse*> iterator(corpse_list);
|
||||
|
||||
iterator.Reset();
|
||||
while(iterator.MoreElements())
|
||||
{
|
||||
if (iterator.GetData()->IsPlayerCorpse())
|
||||
{
|
||||
if (center->DistNoRootNoZ(*iterator.GetData()) < range && strcasecmp(iterator.GetData()->GetOwnerName(), client->GetName()) == 0) {
|
||||
return iterator.GetData();
|
||||
}
|
||||
}
|
||||
iterator.Advance();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Corpse* EntityList::GetCorpseByID(uint16 id){
|
||||
LinkedListIterator<Corpse*> iterator(corpse_list);
|
||||
iterator.Reset();
|
||||
|
||||
+2
-1
@@ -156,6 +156,7 @@ public:
|
||||
Raid* GetRaidByLeaderName(const char *leader);
|
||||
|
||||
Corpse* GetCorpseByOwner(Client* client);
|
||||
Corpse* GetCorpseByOwnerWithinRange(Client* client, Mob* center, int range);
|
||||
Corpse* GetCorpseByID(uint16 id);
|
||||
Corpse* GetCorpseByDBID(uint32 dbid);
|
||||
Corpse* GetCorpseByName(const char* name);
|
||||
@@ -357,7 +358,7 @@ public:
|
||||
int GetHatedCount(Mob *attacker, Mob *exclude);
|
||||
void AIYellForHelp(Mob* sender, Mob* attacker);
|
||||
bool AICheckCloseBeneficialSpells(NPC* caster, uint8 iChance, float iRange, uint16 iSpellTypes);
|
||||
bool Merc_AICheckCloseBeneficialSpells(Merc* caster, uint8 iChance, float iRange, uint16 iSpellTypes);
|
||||
bool Merc_AICheckCloseBeneficialSpells(Merc* caster, uint8 iChance, float iRange, uint32 iSpellTypes);
|
||||
Mob* GetTargetForMez(Mob* caster);
|
||||
uint32 CheckNPCsClose(Mob *center);
|
||||
|
||||
|
||||
+681
-134
File diff suppressed because it is too large
Load Diff
+24
-7
@@ -5,6 +5,7 @@
|
||||
#include "npc.h"
|
||||
using namespace std;
|
||||
|
||||
#define MAXMERCS 1
|
||||
#define MERC_DEBUG 0
|
||||
#define TANK 1
|
||||
#define HEALER 2
|
||||
@@ -26,7 +27,7 @@ enum MercStanceType {
|
||||
|
||||
struct MercSpell {
|
||||
uint16 spellid; // <= 0 = no spell
|
||||
uint16 type; // 0 = never, must be one (and only one) of the defined values
|
||||
uint32 type; // 0 = never, must be one (and only one) of the defined values
|
||||
int16 stance; // 0 = all, + = only this stance, - = all except this stance
|
||||
int16 slot;
|
||||
uint16 proc_chance;
|
||||
@@ -60,7 +61,7 @@ public:
|
||||
virtual void AI_Process();
|
||||
|
||||
//virtual bool AICastSpell(Mob* tar, int8 iChance, int16 iSpellTypes);
|
||||
virtual bool AICastSpell(int8 iChance, int16 iSpellTypes);
|
||||
virtual bool AICastSpell(int8 iChance, int32 iSpellTypes);
|
||||
virtual bool AIDoSpellCast(uint16 spellid, Mob* tar, int32 mana_cost, uint32* oDontDoAgainBefore = 0);
|
||||
virtual bool AI_EngagedCastCheck();
|
||||
//virtual bool AI_PursueCastCheck();
|
||||
@@ -73,6 +74,7 @@ public:
|
||||
static bool RemoveMercFromGroup(Merc* merc, Group* group);
|
||||
void ProcessClientZoneChange(Client* mercOwner);
|
||||
static void MercGroupSay(Mob *speaker, const char *msg, ...);
|
||||
Corpse* GetGroupMemberCorpse();
|
||||
|
||||
// Merc Spell Casting Methods
|
||||
int8 GetChanceToCastBySpellType(int16 spellType);
|
||||
@@ -100,21 +102,25 @@ public:
|
||||
static MercSpell GetBestMercSpellForAETaunt(Merc* caster);
|
||||
static MercSpell GetBestMercSpellForTaunt(Merc* caster);
|
||||
static MercSpell GetBestMercSpellForHate(Merc* caster);
|
||||
static MercSpell GetBestMercSpellForCure(Merc* caster, Mob* target);
|
||||
static bool GetNeedsCured(Mob *tar);
|
||||
bool UseDiscipline(int32 spell_id, int32 target);
|
||||
|
||||
virtual bool IsMerc() const { return true; }
|
||||
|
||||
virtual void FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho);
|
||||
static Merc* LoadMerc(Client *c, MercTemplate* merc_template, uint32 merchant_id);
|
||||
static Merc* LoadMerc(Client *c, MercTemplate* merc_template, uint32 merchant_id, bool updateFromDB = false);
|
||||
void UpdateMercInfo(Client *c);
|
||||
void UpdateMercStats(Client *c);
|
||||
void UpdateMercAppearance(Client *c);
|
||||
static const char *GetRandomName();
|
||||
bool Spawn(Client *owner);
|
||||
bool Dismiss();
|
||||
bool Suspend();
|
||||
bool Unsuspend();
|
||||
bool Unsuspend(bool setMaxStats);
|
||||
void Zone();
|
||||
virtual void Depop();
|
||||
virtual bool Save();
|
||||
bool GetDepop() { return p_depop; }
|
||||
|
||||
bool IsDead() { return GetHP() < 0;};
|
||||
@@ -133,10 +139,12 @@ public:
|
||||
uint32 GetMercTemplateID() { return _MercTemplateID; }
|
||||
uint32 GetMercType() { return _MercType; }
|
||||
uint32 GetMercSubType() { return _MercSubType; }
|
||||
uint32 GetProficiencyID() { return _ProficiencyID; }
|
||||
uint8 GetProficiencyID() { return _ProficiencyID; }
|
||||
uint8 GetTierID() { return _TierID; }
|
||||
uint32 GetCostFormula() { return _CostFormula; }
|
||||
uint32 GetMercNameType() { return _NameType; }
|
||||
uint32 GetStance() { return _currentStance; }
|
||||
int GetHatedCount() { return _hatedCount; }
|
||||
|
||||
inline const uint8 GetClientVersion() const { return _OwnerClientVersion; }
|
||||
|
||||
@@ -148,9 +156,12 @@ public:
|
||||
virtual void DoClassAttacks(Mob *target);
|
||||
bool CheckTaunt();
|
||||
bool CheckAETaunt();
|
||||
bool CheckConfidence();
|
||||
bool TryHide();
|
||||
|
||||
// stat functions
|
||||
virtual void CalcBonuses();
|
||||
int32 GetEndurance() const {return cur_end;} //This gets our current endurance
|
||||
inline virtual int16 GetAC() const { return AC; }
|
||||
inline virtual int16 GetATK() const { return ATK; }
|
||||
inline virtual int16 GetATKBonus() const { return itembonuses.ATK + spellbonuses.ATK; }
|
||||
@@ -215,11 +226,13 @@ public:
|
||||
void SetMercType( uint32 type ) { _MercType = type; }
|
||||
void SetMercSubType( uint32 subtype ) { _MercSubType = subtype; }
|
||||
void SetProficiencyID( uint8 proficiency_id ) { _ProficiencyID = proficiency_id; }
|
||||
void SetTierID( uint8 tier_id ) { _TierID = tier_id; }
|
||||
void SetCostFormula( uint8 costformula ) { _CostFormula = costformula; }
|
||||
void SetMercNameType( uint8 nametype ) { _NameType = nametype; }
|
||||
void SetClientVersion(uint8 clientVersion) { _OwnerClientVersion = clientVersion; }
|
||||
void SetSuspended(bool suspended) { _suspended = suspended; }
|
||||
void SetStance( uint32 stance ) { _currentStance = stance; }
|
||||
void SetHatedCount( uint8 count ) { _hatedCount = count; }
|
||||
|
||||
void Sit();
|
||||
void Stand();
|
||||
@@ -283,7 +296,6 @@ private:
|
||||
int32 CalcManaRegenCap();
|
||||
void CalcMaxEndurance(); //This calculates the maximum endurance we can have
|
||||
int32 CalcBaseEndurance(); //Calculates Base End
|
||||
int32 GetEndurance() const {return cur_end;} //This gets our current endurance
|
||||
int32 GetMaxEndurance() const {return max_end;} //This gets our endurance from the last CalcMaxEndurance() call
|
||||
int32 CalcEnduranceRegen(); //Calculates endurance regen used in DoEnduranceRegen()
|
||||
int32 CalcEnduranceRegenCap();
|
||||
@@ -331,6 +343,7 @@ private:
|
||||
uint32 _MercType;
|
||||
uint32 _MercSubType;
|
||||
uint8 _ProficiencyID;
|
||||
uint8 _TierID;
|
||||
uint8 _CostFormula;
|
||||
uint8 _NameType;
|
||||
uint8 _OwnerClientVersion;
|
||||
@@ -342,11 +355,15 @@ private:
|
||||
bool _medding;
|
||||
bool _suspended;
|
||||
bool p_depop;
|
||||
bool _check_confidence;
|
||||
bool _lost_confidence;
|
||||
int _hatedCount;
|
||||
uint32 owner_char_id;
|
||||
const NPCType* ourNPCData;
|
||||
|
||||
Timer endupkeep_timer;
|
||||
Timer rest_timer;
|
||||
Timer confidence_timer;
|
||||
};
|
||||
|
||||
#endif // MERC_H
|
||||
#endif // MERC_H
|
||||
|
||||
@@ -65,6 +65,7 @@ const int SpellType_Charm=4096;
|
||||
const int SpellType_Slow = 8192;
|
||||
const int SpellType_Debuff = 16384;
|
||||
const int SpellType_Cure = 32768;
|
||||
const int SpellType_Resurrect = 65536;
|
||||
|
||||
const int SpellTypes_Detrimental = SpellType_Nuke|SpellType_Root|SpellType_Lifetap|SpellType_Snare|SpellType_DOT|SpellType_Dispel|SpellType_Mez|SpellType_Charm|SpellType_Debuff|SpellType_Slow;
|
||||
const int SpellTypes_Beneficial = SpellType_Heal|SpellType_Buff|SpellType_Escape|SpellType_Pet|SpellType_InCombatBuff|SpellType_Cure;
|
||||
|
||||
+5
-4
@@ -660,7 +660,7 @@ void Zone::LoadMercTemplates(){
|
||||
mysql_free_result(DatasetResult);
|
||||
}
|
||||
|
||||
if(!database.RunQuery(Query, MakeAnyLenString(&Query, "SELECT DISTINCT MTem.merc_template_id, MTyp.dbstring AS merc_type_id, MTem.dbstring AS merc_subtype_id, MTyp.race_id, MS.class_id, MTyp.proficiency_id, 0 AS CostFormula, MTem.clientversion, MTem.merc_npc_type_id FROM merc_types MTyp, merc_templates MTem, merc_subtypes MS WHERE MTem.merc_type_id = MTyp.merc_type_id AND MTem.merc_subtype_id = MS.merc_subtype_id ORDER BY MTyp.race_id, MS.class_id, MTyp.proficiency_id;"), TempErrorMessageBuffer, &DatasetResult)) {
|
||||
if(!database.RunQuery(Query, MakeAnyLenString(&Query, "SELECT DISTINCT MTem.merc_template_id, MTyp.dbstring AS merc_type_id, MTem.dbstring AS merc_subtype_id, MTyp.race_id, MS.class_id, MTyp.proficiency_id, MS.tier_id, 0 AS CostFormula, MTem.clientversion, MTem.merc_npc_type_id FROM merc_types MTyp, merc_templates MTem, merc_subtypes MS WHERE MTem.merc_type_id = MTyp.merc_type_id AND MTem.merc_subtype_id = MS.merc_subtype_id ORDER BY MTyp.race_id, MS.class_id, MTyp.proficiency_id;"), TempErrorMessageBuffer, &DatasetResult)) {
|
||||
errorMessage = std::string(TempErrorMessageBuffer);
|
||||
}
|
||||
else {
|
||||
@@ -673,9 +673,10 @@ void Zone::LoadMercTemplates(){
|
||||
tempMercTemplate.RaceID = atoi(DataRow[3]);
|
||||
tempMercTemplate.ClassID = atoi(DataRow[4]);
|
||||
tempMercTemplate.ProficiencyID = atoi(DataRow[5]);
|
||||
tempMercTemplate.CostFormula = atoi(DataRow[6]);
|
||||
tempMercTemplate.ClientVersion = atoi(DataRow[7]);
|
||||
tempMercTemplate.MercNPCID = atoi(DataRow[8]);
|
||||
tempMercTemplate.TierID = atoi(DataRow[6]);
|
||||
tempMercTemplate.CostFormula = atoi(DataRow[7]);
|
||||
tempMercTemplate.ClientVersion = atoi(DataRow[8]);
|
||||
tempMercTemplate.MercNPCID = atoi(DataRow[9]);
|
||||
|
||||
for(std::list<MercStanceInfo>::iterator mercStanceListItr = merc_stances.begin(); mercStanceListItr != merc_stances.end(); mercStanceListItr++) {
|
||||
if(mercStanceListItr->ClassID == tempMercTemplate.ClassID && mercStanceListItr->ProficiencyID == tempMercTemplate.ProficiencyID) {
|
||||
|
||||
+274
@@ -7,6 +7,7 @@
|
||||
#include "../common/rulesys.h"
|
||||
#include "zone.h"
|
||||
#include "client.h"
|
||||
#include "merc.h"
|
||||
#include "groups.h"
|
||||
#include "raids.h"
|
||||
#include <iostream>
|
||||
@@ -1632,6 +1633,279 @@ const NPCType* ZoneDatabase::GetMercType(uint32 id, uint16 raceid, uint32 client
|
||||
return npc;
|
||||
}
|
||||
|
||||
bool ZoneDatabase::LoadMercInfo(Client *c) {
|
||||
bool loaded = false;
|
||||
|
||||
if(c->GetEPP().merc_name[0] != 0) {
|
||||
std::string errorMessage;
|
||||
char* Query = 0;
|
||||
char TempErrorMessageBuffer[MYSQL_ERRMSG_SIZE];
|
||||
MYSQL_RES* DatasetResult;
|
||||
MYSQL_ROW DataRow;
|
||||
//char name[64];
|
||||
|
||||
//CleanMobName(c->GetEPP().merc_name, name);
|
||||
|
||||
if(!database.RunQuery(Query, MakeAnyLenString(&Query, "SELECT MercID, Slot, Name, TemplateID, SuspendedTime, IsSuspended, TimerRemaining, Gender, StanceID, HP, Mana, Endurance, Face, LuclinHairStyle, LuclinHairColor, LuclinEyeColor, LuclinEyeColor2, LuclinBeardColor, LuclinBeard, DrakkinHeritage, DrakkinTattoo, DrakkinDetails FROM mercs WHERE OwnerCharacterID = '%i' ORDER BY Slot", c->CharacterID()), TempErrorMessageBuffer, &DatasetResult)) {
|
||||
errorMessage = std::string(TempErrorMessageBuffer);
|
||||
}
|
||||
else {
|
||||
while(DataRow = mysql_fetch_row(DatasetResult)) {
|
||||
uint8 slot = atoi(DataRow[1]);
|
||||
c->GetMercInfo(slot).mercid = atoi(DataRow[0]);
|
||||
c->GetMercInfo(slot).slot = slot;
|
||||
snprintf(c->GetMercInfo(slot).merc_name, 64, "%s", std::string(DataRow[2]).c_str());
|
||||
c->GetMercInfo(slot).MercTemplateID = atoi(DataRow[3]);
|
||||
c->GetMercInfo(slot).SuspendedTime = atoi(DataRow[4]);
|
||||
c->GetMercInfo(slot).IsSuspended = atoi(DataRow[5]) == 1 ? true : false;
|
||||
c->GetMercInfo(slot).MercTimerRemaining = atoi(DataRow[6]);
|
||||
c->GetMercInfo(slot).Gender = atoi(DataRow[7]);
|
||||
c->GetMercInfo(slot).State = atoi(DataRow[8]);
|
||||
c->GetMercInfo(slot).hp = atoi(DataRow[9]);
|
||||
c->GetMercInfo(slot).mana = atoi(DataRow[10]);
|
||||
c->GetMercInfo(slot).endurance = atoi(DataRow[11]);
|
||||
c->GetMercInfo(slot).face = atoi(DataRow[12]);
|
||||
c->GetMercInfo(slot).luclinHairStyle = atoi(DataRow[13]);
|
||||
c->GetMercInfo(slot).luclinHairColor = atoi(DataRow[14]);
|
||||
c->GetMercInfo(slot).luclinEyeColor = atoi(DataRow[15]);
|
||||
c->GetMercInfo(slot).luclinEyeColor2 = atoi(DataRow[16]);
|
||||
c->GetMercInfo(slot).luclinBeardColor = atoi(DataRow[17]);
|
||||
c->GetMercInfo(slot).luclinBeard = atoi(DataRow[18]);
|
||||
c->GetMercInfo(slot).drakkinHeritage = atoi(DataRow[19]);
|
||||
c->GetMercInfo(slot).drakkinTattoo = atoi(DataRow[20]);
|
||||
c->GetMercInfo(slot).drakkinDetails = atoi(DataRow[21]);
|
||||
loaded = true;
|
||||
}
|
||||
|
||||
mysql_free_result(DatasetResult);
|
||||
}
|
||||
|
||||
safe_delete_array(Query);
|
||||
}
|
||||
|
||||
return loaded;
|
||||
}
|
||||
|
||||
bool ZoneDatabase::SaveMerc(Merc *merc) {
|
||||
Client *owner = merc->GetMercOwner();
|
||||
bool Result = false;
|
||||
std::string errorMessage;
|
||||
|
||||
if(!owner) {
|
||||
return false;
|
||||
}
|
||||
|
||||
char* Query = 0;
|
||||
char TempErrorMessageBuffer[MYSQL_ERRMSG_SIZE];
|
||||
uint32 affectedRows = 0;
|
||||
|
||||
if(merc->GetMercID() == 0) {
|
||||
// New merc record
|
||||
uint32 TempNewMercID = 0;
|
||||
if(!database.RunQuery(Query, MakeAnyLenString(&Query, "INSERT INTO mercs (OwnerCharacterID, Slot, Name, TemplateID, SuspendedTime, IsSuspended, TimerRemaining, Gender, StanceID, HP, Mana, Endurance, Face, LuclinHairStyle, LuclinHairColor, LuclinEyeColor, LuclinEyeColor2, LuclinBeardColor, LuclinBeard, DrakkinHeritage, DrakkinTattoo, DrakkinDetails) VALUES('%u', '%u', '%s', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%i', '%i', '%i', '%i', '%i', '%i', '%i', '%i', '%i', '%i')", merc->GetMercCharacterID(), owner->GetNumMercs(), merc->GetCleanName(), merc->GetMercTemplateID(), owner->GetMercInfo().SuspendedTime, merc->IsSuspended(), owner->GetMercInfo().MercTimerRemaining, merc->GetGender(), merc->GetStance(), merc->GetHP(), merc->GetMana(), merc->GetEndurance(), merc->GetLuclinFace(), merc->GetHairStyle(), merc->GetHairColor(), merc->GetEyeColor1(), merc->GetEyeColor2(), merc->GetBeardColor(), merc->GetBeard(), merc->GetDrakkinHeritage(), merc->GetDrakkinTattoo(), merc->GetDrakkinDetails() ), TempErrorMessageBuffer, 0, &affectedRows, &TempNewMercID)) {
|
||||
errorMessage = std::string(TempErrorMessageBuffer);
|
||||
}
|
||||
else {
|
||||
merc->SetMercID(TempNewMercID);
|
||||
Result = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Update existing merc record
|
||||
if(!database.RunQuery(Query, MakeAnyLenString(&Query, "UPDATE mercs SET OwnerCharacterID = '%u', Slot = '%u', Name = '%s', TemplateID = '%u', SuspendedTime = '%u', IsSuspended = '%u', TimerRemaining = '%u', Gender = '%u', StanceID = '%u', HP = '%u', Mana = '%u', Endurance = '%u', Face = '%i', LuclinHairStyle = '%i', LuclinHairColor = '%i', LuclinEyeColor = '%i', LuclinEyeColor2 = '%i', LuclinBeardColor = '%i', LuclinBeard = '%i', DrakkinHeritage = '%i', DrakkinTattoo = '%i', DrakkinDetails = '%i' WHERE MercID = '%u'", merc->GetMercCharacterID(), owner->GetMercSlot(), merc->GetCleanName(), merc->GetMercTemplateID(), owner->GetMercInfo().SuspendedTime, merc->IsSuspended(), owner->GetMercInfo().MercTimerRemaining, merc->GetGender(), merc->GetStance(), merc->GetHP(), merc->GetMana(), merc->GetEndurance(), merc->GetLuclinFace(), merc->GetHairStyle(), merc->GetHairColor(), merc->GetEyeColor1(), merc->GetEyeColor2(), merc->GetBeardColor(), merc->GetBeard(), merc->GetDrakkinHeritage(), merc->GetDrakkinTattoo(), merc->GetDrakkinDetails(), merc->GetMercID()), TempErrorMessageBuffer, 0, &affectedRows)) {
|
||||
errorMessage = std::string(TempErrorMessageBuffer);
|
||||
}
|
||||
else {
|
||||
Result = true;
|
||||
//time(&_startTotalPlayTime);
|
||||
}
|
||||
}
|
||||
|
||||
safe_delete(Query);
|
||||
|
||||
if(!errorMessage.empty() || (Result && affectedRows != 1)) {
|
||||
if(owner && !errorMessage.empty())
|
||||
owner->Message(13, errorMessage.c_str());
|
||||
else if(owner)
|
||||
owner->Message(13, std::string("Unable to save merc to the database.").c_str());
|
||||
|
||||
Result = false;
|
||||
}
|
||||
else {
|
||||
merc->UpdateMercInfo(owner);
|
||||
database.SaveMercBuffs(merc);
|
||||
//database.SaveMercStance(this);
|
||||
//database.SaveMercTimers(this);
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
void ZoneDatabase::SaveMercBuffs(Merc *merc) {
|
||||
Buffs_Struct *buffs = merc->GetBuffs();
|
||||
std::string errorMessage;
|
||||
char* Query = 0;
|
||||
char TempErrorMessageBuffer[MYSQL_ERRMSG_SIZE];
|
||||
int BuffCount = 0;
|
||||
int InsertCount = 0;
|
||||
|
||||
uint32 buff_count = merc->GetMaxBuffSlots();
|
||||
while(BuffCount < BUFF_COUNT) {
|
||||
if(buffs[BuffCount].spellid > 0 && buffs[BuffCount].spellid != SPELL_UNKNOWN) {
|
||||
if(InsertCount == 0) {
|
||||
// Remove any existing buff saves
|
||||
if(!database.RunQuery(Query, MakeAnyLenString(&Query, "DELETE FROM mercbuffs WHERE MercId = %u", merc->GetMercID()), TempErrorMessageBuffer)) {
|
||||
errorMessage = std::string(TempErrorMessageBuffer);
|
||||
safe_delete(Query);
|
||||
Query = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int IsPersistent = 0;
|
||||
|
||||
if(buffs[BuffCount].persistant_buff)
|
||||
IsPersistent = 1;
|
||||
else
|
||||
IsPersistent = 0;
|
||||
|
||||
if(!database.RunQuery(Query, MakeAnyLenString(&Query, "INSERT INTO mercbuffs (MercId, SpellId, CasterLevel, DurationFormula, "
|
||||
"TicsRemaining, PoisonCounters, DiseaseCounters, CurseCounters, CorruptionCounters, HitCount, MeleeRune, MagicRune, "
|
||||
"DeathSaveSuccessChance, CasterAARank, Persistent) VALUES (%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u);",
|
||||
merc->GetMercID(), buffs[BuffCount].spellid, buffs[BuffCount].casterlevel, spells[buffs[BuffCount].spellid].buffdurationformula,
|
||||
buffs[BuffCount].ticsremaining,
|
||||
CalculatePoisonCounters(buffs[BuffCount].spellid) > 0 ? buffs[BuffCount].counters : 0,
|
||||
CalculateDiseaseCounters(buffs[BuffCount].spellid) > 0 ? buffs[BuffCount].counters : 0,
|
||||
CalculateCurseCounters(buffs[BuffCount].spellid) > 0 ? buffs[BuffCount].counters : 0,
|
||||
CalculateCorruptionCounters(buffs[BuffCount].spellid) > 0 ? buffs[BuffCount].counters : 0,
|
||||
buffs[BuffCount].numhits, buffs[BuffCount].melee_rune, buffs[BuffCount].magic_rune,
|
||||
buffs[BuffCount].deathSaveSuccessChance,
|
||||
buffs[BuffCount].deathsaveCasterAARank, IsPersistent), TempErrorMessageBuffer)) {
|
||||
errorMessage = std::string(TempErrorMessageBuffer);
|
||||
safe_delete(Query);
|
||||
Query = 0;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
safe_delete(Query);
|
||||
Query = 0;
|
||||
InsertCount++;
|
||||
}
|
||||
}
|
||||
|
||||
BuffCount++;
|
||||
}
|
||||
|
||||
if(!errorMessage.empty()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error Saving Merc Buffs: %s", errorMessage.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void ZoneDatabase::LoadMercBuffs(Merc *merc) {
|
||||
Buffs_Struct *buffs = merc->GetBuffs();
|
||||
uint32 max_slots = merc->GetMaxBuffSlots();
|
||||
std::string errorMessage;
|
||||
char* Query = 0;
|
||||
char TempErrorMessageBuffer[MYSQL_ERRMSG_SIZE];
|
||||
MYSQL_RES* DatasetResult;
|
||||
MYSQL_ROW DataRow;
|
||||
|
||||
bool BuffsLoaded = false;
|
||||
|
||||
if(!database.RunQuery(Query, MakeAnyLenString(&Query, "SELECT SpellId, CasterLevel, DurationFormula, TicsRemaining, PoisonCounters, DiseaseCounters, CurseCounters, CorruptionCounters, HitCount, MeleeRune, MagicRune, DeathSaveSuccessChance, CasterAARank, Persistent FROM mercbuffs WHERE MercId = %u", merc->GetMercID()), TempErrorMessageBuffer, &DatasetResult)) {
|
||||
errorMessage = std::string(TempErrorMessageBuffer);
|
||||
}
|
||||
else {
|
||||
int BuffCount = 0;
|
||||
|
||||
while(DataRow = mysql_fetch_row(DatasetResult)) {
|
||||
if(BuffCount == BUFF_COUNT)
|
||||
break;
|
||||
|
||||
buffs[BuffCount].spellid = atoi(DataRow[0]);
|
||||
buffs[BuffCount].casterlevel = atoi(DataRow[1]);
|
||||
buffs[BuffCount].ticsremaining = atoi(DataRow[3]);
|
||||
|
||||
if(CalculatePoisonCounters(buffs[BuffCount].spellid) > 0) {
|
||||
buffs[BuffCount].counters = atoi(DataRow[4]);
|
||||
} else if(CalculateDiseaseCounters(buffs[BuffCount].spellid) > 0) {
|
||||
buffs[BuffCount].counters = atoi(DataRow[5]);
|
||||
} else if(CalculateCurseCounters(buffs[BuffCount].spellid) > 0) {
|
||||
buffs[BuffCount].counters = atoi(DataRow[6]);
|
||||
} else if(CalculateCorruptionCounters(buffs[BuffCount].spellid) > 0) {
|
||||
buffs[BuffCount].counters = atoi(DataRow[7]);
|
||||
}
|
||||
buffs[BuffCount].numhits = atoi(DataRow[8]);
|
||||
buffs[BuffCount].melee_rune = atoi(DataRow[9]);
|
||||
buffs[BuffCount].magic_rune = atoi(DataRow[10]);
|
||||
buffs[BuffCount].deathSaveSuccessChance = atoi(DataRow[11]);
|
||||
buffs[BuffCount].deathsaveCasterAARank = atoi(DataRow[12]);
|
||||
buffs[BuffCount].casterid = 0;
|
||||
|
||||
bool IsPersistent = false;
|
||||
|
||||
if(atoi(DataRow[13]))
|
||||
IsPersistent = true;
|
||||
|
||||
buffs[BuffCount].persistant_buff = IsPersistent;
|
||||
|
||||
BuffCount++;
|
||||
}
|
||||
|
||||
mysql_free_result(DatasetResult);
|
||||
|
||||
BuffsLoaded = true;
|
||||
}
|
||||
|
||||
safe_delete(Query);
|
||||
Query = 0;
|
||||
|
||||
if(errorMessage.empty() && BuffsLoaded) {
|
||||
if(!database.RunQuery(Query, MakeAnyLenString(&Query, "DELETE FROM mercbuffs WHERE MercId = %u", merc->GetMercID()), TempErrorMessageBuffer)) {
|
||||
errorMessage = std::string(TempErrorMessageBuffer);
|
||||
safe_delete(Query);
|
||||
Query = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(!errorMessage.empty()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error Loading Merc Buffs: %s", errorMessage.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
bool ZoneDatabase::DeleteMerc(uint32 merc_id) {
|
||||
std::string errorMessage;
|
||||
bool Result = false;
|
||||
int TempCounter = 0;
|
||||
|
||||
if(merc_id > 0) {
|
||||
char* Query = 0;
|
||||
char TempErrorMessageBuffer[MYSQL_ERRMSG_SIZE];
|
||||
|
||||
// TODO: These queries need to be ran together as a transaction.. ie, if one or more fail then they all will fail to commit to the database.
|
||||
|
||||
if(!database.RunQuery(Query, MakeAnyLenString(&Query, "DELETE FROM mercbuffs WHERE MercID = '%u'", merc_id), TempErrorMessageBuffer)) {
|
||||
errorMessage = std::string(TempErrorMessageBuffer);
|
||||
}
|
||||
else
|
||||
TempCounter++;
|
||||
|
||||
if(!database.RunQuery(Query, MakeAnyLenString(&Query, "DELETE FROM mercs WHERE MercID = '%u'", merc_id), TempErrorMessageBuffer)) {
|
||||
errorMessage = std::string(TempErrorMessageBuffer);
|
||||
}
|
||||
else
|
||||
TempCounter++;
|
||||
|
||||
if(TempCounter == 2)
|
||||
Result = true;
|
||||
}
|
||||
|
||||
if(!errorMessage.empty()) {
|
||||
LogFile->write(EQEMuLog::Error, "Error Deleting Merc: %s", errorMessage.c_str());
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
uint8 ZoneDatabase::GetGridType(uint32 grid, uint32 zoneid ) {
|
||||
char *query = 0;
|
||||
|
||||
+33
-4
@@ -110,6 +110,7 @@ struct MercTemplate {
|
||||
uint8 ClassID;
|
||||
uint32 MercNPCID;
|
||||
uint8 ProficiencyID;
|
||||
uint8 TierID;
|
||||
uint8 CostFormula; // To determine cost to client
|
||||
uint32 ClientVersion; // Only send valid mercs per expansion
|
||||
uint8 MercNameType; // Determines if merc gets random name or default text
|
||||
@@ -119,18 +120,35 @@ struct MercTemplate {
|
||||
};
|
||||
|
||||
struct MercInfo {
|
||||
MercTemplate myTemplate;
|
||||
uint32 mercid;
|
||||
uint8 slot;
|
||||
char merc_name[64];
|
||||
uint32 MercTemplateID;
|
||||
const MercTemplate* myTemplate;
|
||||
uint32 SuspendedTime;
|
||||
bool IsSuspended;
|
||||
uint32 MercTimerRemaining;
|
||||
uint8 Gender;
|
||||
int32 State;
|
||||
int32 hp;
|
||||
int32 mana;
|
||||
int32 endurance;
|
||||
uint8 face;
|
||||
uint8 luclinHairStyle;
|
||||
uint8 luclinHairColor;
|
||||
uint8 luclinEyeColor;
|
||||
uint8 luclinEyeColor2;
|
||||
uint8 luclinBeardColor;
|
||||
uint8 luclinBeard;
|
||||
uint32 drakkinHeritage;
|
||||
uint32 drakkinTattoo;
|
||||
uint32 drakkinDetails;
|
||||
};
|
||||
|
||||
struct MercSpellEntry {
|
||||
uint8 proficiencyid;
|
||||
uint16 spellid; // <= 0 = no spell
|
||||
uint16 type; // 0 = never, must be one (and only one) of the defined values
|
||||
uint32 type; // 0 = never, must be one (and only one) of the defined values
|
||||
int16 stance; // 0 = all, + = only this stance, - = all except this stance
|
||||
uint8 minlevel;
|
||||
uint8 maxlevel;
|
||||
@@ -325,7 +343,6 @@ public:
|
||||
* NPCs
|
||||
*/
|
||||
const NPCType* GetNPCType(uint32 id);
|
||||
const NPCType* GetMercType(uint32 id, uint16 raceid, uint32 clientlevel);
|
||||
uint32 NPCSpawnDB(uint8 command, const char* zone, uint32 zone_version, Client *c, NPC* spawn = 0, uint32 extra = 0); // 0 = Create 1 = Add; 2 = Update; 3 = Remove; 4 = Delete
|
||||
bool SetSpecialAttkFlag(uint8 id, const char* flag);
|
||||
bool GetPetEntry(const char *pet_type, PetRecord *into);
|
||||
@@ -335,7 +352,19 @@ public:
|
||||
void AddLootDropToNPC(NPC* npc,uint32 lootdrop_id, ItemList* itemlist, uint8 droplimit, uint8 mindrop);
|
||||
uint32 GetMaxNPCSpellsID();
|
||||
DBnpcspells_Struct* GetNPCSpells(uint32 iDBSpellsID);
|
||||
|
||||
|
||||
/*
|
||||
* Mercs
|
||||
*/
|
||||
const NPCType* GetMercType(uint32 id, uint16 raceid, uint32 clientlevel);
|
||||
void SaveMercBuffs(Merc *merc);
|
||||
void LoadMercBuffs(Merc *merc);
|
||||
bool LoadMercInfo(Client *c);
|
||||
bool SaveMerc(Merc *merc);
|
||||
bool DeleteMerc(uint32 merc_id);
|
||||
//void LoadMercTypesForMercMerchant(NPC *merchant);
|
||||
//void LoadMercsForMercMerchant(NPC *merchant);
|
||||
|
||||
/*
|
||||
* Petitions
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user