Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Paul Coene
2015-11-20 12:04:11 -05:00
65 changed files with 1484 additions and 377 deletions
+8 -8
View File
@@ -1189,21 +1189,21 @@ int32 Mob::CheckHealAggroAmount(uint16 spell_id, Mob *target, uint32 heal_possib
}
void Mob::AddFeignMemory(Client* attacker) {
if(feign_memory_list.empty() && AIfeignremember_timer != nullptr)
AIfeignremember_timer->Start(AIfeignremember_delay);
if(feign_memory_list.empty() && AI_feign_remember_timer != nullptr)
AI_feign_remember_timer->Start(AIfeignremember_delay);
feign_memory_list.insert(attacker->CharacterID());
}
void Mob::RemoveFromFeignMemory(Client* attacker) {
feign_memory_list.erase(attacker->CharacterID());
if(feign_memory_list.empty() && AIfeignremember_timer != nullptr)
AIfeignremember_timer->Disable();
if(feign_memory_list.empty() && AI_feign_remember_timer != nullptr)
AI_feign_remember_timer->Disable();
if(feign_memory_list.empty())
{
minLastFightingDelayMoving = RuleI(NPC, LastFightingDelayMovingMin);
maxLastFightingDelayMoving = RuleI(NPC, LastFightingDelayMovingMax);
if(AIfeignremember_timer != nullptr)
AIfeignremember_timer->Disable();
if(AI_feign_remember_timer != nullptr)
AI_feign_remember_timer->Disable();
}
}
@@ -1220,8 +1220,8 @@ void Mob::ClearFeignMemory() {
feign_memory_list.clear();
minLastFightingDelayMoving = RuleI(NPC, LastFightingDelayMovingMin);
maxLastFightingDelayMoving = RuleI(NPC, LastFightingDelayMovingMax);
if(AIfeignremember_timer != nullptr)
AIfeignremember_timer->Disable();
if(AI_feign_remember_timer != nullptr)
AI_feign_remember_timer->Disable();
}
bool Mob::PassCharismaCheck(Mob* caster, uint16 spell_id) {
+12 -12
View File
@@ -6,7 +6,7 @@
#include "quest_parser_collection.h"
#include "../common/string_util.h"
extern volatile bool ZoneLoaded;
extern volatile bool is_zone_loaded;
// This constructor is used during the bot create command
Bot::Bot(NPCType npcTypeData, Client* botOwner) : NPC(&npcTypeData, nullptr, glm::vec4(), 0, false), rest_timer(1) {
@@ -2286,7 +2286,7 @@ bool Bot::Process() {
BuffProcess();
CalcRestState();
if(curfp)
if(currently_fleeing)
ProcessFlee();
if(GetHP() < GetMaxHP())
@@ -2685,7 +2685,7 @@ void Bot::AI_Process() {
if(GetHasBeenSummoned()) {
if(IsBotCaster() || IsBotArcher()) {
if (AImovement_timer->Check()) {
if (AI_movement_timer->Check()) {
if(!GetTarget() || (IsBotCaster() && !IsBotCasterCombatRange(GetTarget())) || (IsBotArcher() && IsArcheryRange(GetTarget())) || (DistanceSquaredNoZ(static_cast<glm::vec3>(m_Position), m_PreSummonLocation) < 10)) {
if(GetTarget())
FaceTarget(GetTarget());
@@ -2831,7 +2831,7 @@ void Bot::AI_Process() {
}
}
if(AImovement_timer->Check()) {
if(AI_movement_timer->Check()) {
if(!IsMoving() && GetClass() == ROGUE && !BehindMob(GetTarget(), GetX(), GetY())) {
// Move the rogue to behind the mob
float newX = 0;
@@ -2967,7 +2967,7 @@ void Bot::AI_Process() {
AI_PursueCastCheck();
}
if (AImovement_timer->Check()) {
if (AI_movement_timer->Check()) {
if(!IsRooted()) {
Log.Out(Logs::Detail, Logs::AI, "Pursuing %s while engaged.", GetTarget()->GetCleanName());
CalculateNewPosition2(GetTarget()->GetX(), GetTarget()->GetY(), GetTarget()->GetZ(), GetRunspeed());
@@ -2995,7 +2995,7 @@ void Bot::AI_Process() {
if (m_PlayerState & static_cast<uint32>(PlayerState::Aggressive))
SendRemovePlayerState(PlayerState::Aggressive);
if(!IsMoving() && AIthink_timer->Check() && !spellend_timer.Enabled()) {
if(!IsMoving() && AI_think_timer->Check() && !spellend_timer.Enabled()) {
if(GetBotStance() != BotStancePassive) {
if(!AI_IdleCastCheck() && !IsCasting())
BotMeditate(true);
@@ -3004,7 +3004,7 @@ void Bot::AI_Process() {
BotMeditate(true);
}
if(AImovement_timer->Check()) {
if(AI_movement_timer->Check()) {
if(GetFollowID()) {
Mob* follow = entity_list.GetMob(GetFollowID());
if(follow) {
@@ -3737,9 +3737,9 @@ Bot* Bot::LoadBot(uint32 botID, std::string* errorMessage)
" `drakkin_tattoo`,"
" `drakkin_details`,"
" `ac`," /*not in-use[26]*/
" `atk`,"
" `atk`," /*not in-use[27]*/
" `hp`,"
" `mana`," /*not in-use[29]*/
" `mana`,"
" `str`," /*not in-use[30]*/
" `sta`," /*not in-use[31]*/
" `cha`," /*not in-use[32]*/
@@ -3753,8 +3753,8 @@ Bot* Bot::LoadBot(uint32 botID, std::string* errorMessage)
" `poison`," /*not in-use[40]*/
" `disease`," /*not in-use[41]*/
" `corruption`," /*not in-use[42]*/
" `show_helm`,"
" `follow_distance`"
" `show_helm`,"//43
" `follow_distance`"//44
" FROM `bot_data`"
" WHERE `bot_id` = '%u'",
botID
@@ -3791,8 +3791,8 @@ Bot* Bot::LoadBot(uint32 botID, std::string* errorMessage)
atoi(row[23]),
atoi(row[24]),
atoi(row[25]),
atoi(row[27]),
atoi(row[28]),
atoi(row[29]),
defaultNPCTypeStruct.MR,
defaultNPCTypeStruct.CR,
defaultNPCTypeStruct.DR,
+2 -2
View File
@@ -53,7 +53,7 @@ extern volatile bool RunLoops;
extern QueryServ* QServ;
extern EntityList entity_list;
extern Zone* zone;
extern volatile bool ZoneLoaded;
extern volatile bool is_zone_loaded;
extern WorldServer worldserver;
extern uint32 numclients;
extern PetitionList petition_list;
@@ -371,7 +371,7 @@ Client::~Client() {
GetTarget()->IsTargeted(-1);
//if we are in a group and we are not zoning, force leave the group
if(isgrouped && !zoning && ZoneLoaded)
if(isgrouped && !zoning && is_zone_loaded)
LeaveGroup();
UpdateWho(2);
+14 -15
View File
@@ -66,7 +66,7 @@
extern QueryServ* QServ;
extern Zone* zone;
extern volatile bool ZoneLoaded;
extern volatile bool is_zone_loaded;
extern WorldServer worldserver;
extern PetitionList petition_list;
extern EntityList entity_list;
@@ -386,6 +386,7 @@ void MapOpcodes()
ConnectedOpcodes[OP_WhoAllRequest] = &Client::Handle_OP_WhoAllRequest;
ConnectedOpcodes[OP_WorldUnknown001] = &Client::Handle_OP_Ignore;
ConnectedOpcodes[OP_XTargetAutoAddHaters] = &Client::Handle_OP_XTargetAutoAddHaters;
ConnectedOpcodes[OP_XTargetOpen] = &Client::Handle_OP_XTargetOpen;
ConnectedOpcodes[OP_XTargetRequest] = &Client::Handle_OP_XTargetRequest;
ConnectedOpcodes[OP_YellForHelp] = &Client::Handle_OP_YellForHelp;
ConnectedOpcodes[OP_ZoneChange] = &Client::Handle_OP_ZoneChange;
@@ -6682,20 +6683,6 @@ void Client::Handle_OP_GuildBank(const EQApplicationPacket *app)
uint32 Action = VARSTRUCT_DECODE_TYPE(uint32, Buffer);
uint32 sentAction = Action;
if (GetClientVersion() >= ClientVersion::RoF)
{
Action += 1;
/*
// Need to find all of the action types for RoF and switch case here
switch(Action)
{
case 4:
Action = 5;
break;
}
*/
}
if (!IsInAGuild())
{
Message(13, "You must be in a Guild to use the Guild Bank.");
@@ -13925,6 +13912,18 @@ void Client::Handle_OP_XTargetAutoAddHaters(const EQApplicationPacket *app)
XTargetAutoAddHaters = app->ReadUInt8(0);
}
void Client::Handle_OP_XTargetOpen(const EQApplicationPacket *app)
{
if (app->size != 4) {
Log.Out(Logs::General, Logs::None, "Size mismatch in OP_XTargetOpen, expected 1, got %i", app->size);
DumpPacket(app);
return;
}
auto outapp = new EQApplicationPacket(OP_XTargetOpenResponse, 0);
FastQueuePacket(&outapp);
}
void Client::Handle_OP_XTargetRequest(const EQApplicationPacket *app)
{
if (app->size < 12)
+1
View File
@@ -292,6 +292,7 @@
void Handle_OP_WearChange(const EQApplicationPacket *app);
void Handle_OP_WhoAllRequest(const EQApplicationPacket *app);
void Handle_OP_XTargetAutoAddHaters(const EQApplicationPacket *app);
void Handle_OP_XTargetOpen(const EQApplicationPacket *app);
void Handle_OP_XTargetRequest(const EQApplicationPacket *app);
void Handle_OP_YellForHelp(const EQApplicationPacket *app);
void Handle_OP_ZoneChange(const EQApplicationPacket *app);
+1 -1
View File
@@ -55,7 +55,7 @@
extern QueryServ* QServ;
extern Zone* zone;
extern volatile bool ZoneLoaded;
extern volatile bool is_zone_loaded;
extern WorldServer worldserver;
extern PetitionList petition_list;
extern EntityList entity_list;
+46 -3
View File
@@ -334,6 +334,7 @@ int command_init(void) {
command_add("reloadallrules", "Executes a reload of all rules.", 80, command_reloadallrules) ||
command_add("reloademote", "Reloads NPC Emotes", 80, command_reloademote) ||
command_add("reloadlevelmods", nullptr,255, command_reloadlevelmods) ||
command_add("reloadperlexportsettings", nullptr, 255, command_reloadperlexportsettings) ||
command_add("reloadqst", " - Clear quest cache (any argument causes it to also stop all timers)", 150, command_reloadqst) ||
command_add("reloadquest", " - Clear quest cache (any argument causes it to also stop all timers)", 150, command_reloadqst) ||
command_add("reloadrulesworld", "Executes a reload of all rules in world specifically.", 80, command_reloadworldrules) ||
@@ -343,6 +344,7 @@ int command_init(void) {
command_add("reloadzonepoints", "- Reload zone points from database", 150, command_reloadzps) ||
command_add("reloadzps", nullptr,0, command_reloadzps) ||
command_add("repop", "[delay] - Repop the zone with optional delay", 100, command_repop) ||
command_add("repopclose", "[distance in units] Repops only NPC's nearby for fast development purposes", 100, command_repopclose) ||
command_add("resetaa", "- Resets a Player's AA in their profile and refunds spent AA's to unspent, may disconnect player.", 200, command_resetaa) ||
command_add("resetaa_timer", "Command to reset AA cooldown timers.", 200, command_resetaa_timer) ||
command_add("revoke", "[charname] [1/0] - Makes charname unable to talk on OOC", 200, command_revoke) ||
@@ -3920,9 +3922,11 @@ void command_repop(Client *c, const Seperator *sep)
LinkedListIterator<Spawn2*> iterator(zone->spawn2_list);
iterator.Reset();
while (iterator.MoreElements()) {
std::string query = StringFormat("DELETE FROM respawn_times WHERE id = %lu AND instance_id = %lu",
(unsigned long)iterator.GetData()->GetID(),
(unsigned long)zone->GetInstanceID());
std::string query = StringFormat(
"DELETE FROM respawn_times WHERE id = %lu AND instance_id = %lu",
(unsigned long)iterator.GetData()->GetID(),
(unsigned long)zone->GetInstanceID()
);
auto results = database.QueryDatabase(query);
iterator.Advance();
}
@@ -3939,6 +3943,33 @@ void command_repop(Client *c, const Seperator *sep)
zone->Repop(atoi(sep->arg[timearg])*1000);
}
void command_repopclose(Client *c, const Seperator *sep)
{
int repop_distance = 500;
if (sep->arg[1] && strcasecmp(sep->arg[1], "force") == 0) {
LinkedListIterator<Spawn2*> iterator(zone->spawn2_list);
iterator.Reset();
while (iterator.MoreElements()) {
std::string query = StringFormat(
"DELETE FROM respawn_times WHERE id = %lu AND instance_id = %lu",
(unsigned long)iterator.GetData()->GetID(),
(unsigned long)zone->GetInstanceID()
);
auto results = database.QueryDatabase(query);
iterator.Advance();
}
c->Message(0, "Zone depop: Force resetting spawn timers.");
}
if (sep->IsNumber(1)) {
repop_distance = atoi(sep->arg[1]);
}
c->Message(0, "Zone depoped. Repopping NPC's within %i distance units", repop_distance);
zone->RepopClose(c->GetPosition(), repop_distance);
}
void command_spawnstatus(Client *c, const Seperator *sep)
{
if((sep->arg[1][0] == 'e') | (sep->arg[1][0] == 'E'))
@@ -10768,4 +10799,16 @@ void command_apply_shared_memory(Client *c, const Seperator *sep) {
strcpy((char*)pack.pBuffer, hotfix_name.c_str());
}
worldserver.SendPacket(&pack);
}
void command_reloadperlexportsettings(Client *c, const Seperator *sep)
{
if (c)
{
ServerPacket *pack = new ServerPacket(ServerOP_ReloadPerlExportSettings, 0);
worldserver.SendPacket(pack);
c->Message(13, "Successfully sent the packet to world to reload Perl Export settings");
safe_delete(pack);
}
}
+2
View File
@@ -187,6 +187,7 @@ void command_myskills(Client *c, const Seperator *sep);
void command_depop(Client *c, const Seperator *sep);
void command_depopzone(Client *c, const Seperator *sep);
void command_repop(Client *c, const Seperator *sep);
void command_repopclose(Client *c, const Seperator *sep);
void command_spawnstatus(Client *c, const Seperator *sep);
void command_nukebuffs(Client *c, const Seperator *sep);
void command_zuwcoords(Client *c, const Seperator *sep);
@@ -332,6 +333,7 @@ void command_load_shared_memory(Client *c, const Seperator *sep);
void command_apply_shared_memory(Client *c, const Seperator *sep);
void command_untraindisc(Client *c, const Seperator *sep);
void command_untraindiscs(Client *c, const Seperator *sep);
void command_reloadperlexportsettings(Client *c, const Seperator *sep);
#ifdef EQPROFILE
void command_profiledump(Client *c, const Seperator *sep);
+25 -10
View File
@@ -183,15 +183,31 @@ int PerlembParser::EventCommon(QuestEventID event, uint32 objid, const char * da
int char_id = 0;
ExportCharID(package_name, char_id, npcmob, mob);
ExportQGlobals(isPlayerQuest, isGlobalPlayerQuest, isGlobalNPC, isItemQuest, isSpellQuest,
package_name, npcmob, mob, char_id);
/* Check for QGlobal export event enable */
if (parse->perl_event_export_settings[event].qglobals){
ExportQGlobals(isPlayerQuest, isGlobalPlayerQuest, isGlobalNPC, isItemQuest, isSpellQuest, package_name, npcmob, mob, char_id);
}
//ExportGenericVariables();
ExportMobVariables(isPlayerQuest, isGlobalPlayerQuest, isGlobalNPC, isItemQuest, isSpellQuest,
package_name, mob, npcmob);
ExportZoneVariables(package_name);
ExportItemVariables(package_name, mob);
ExportEventVariables(package_name, event, objid, data, npcmob, iteminst, mob, extradata, extra_pointers);
/* Check for Mob export event enable */
if (parse->perl_event_export_settings[event].mob){
ExportMobVariables(isPlayerQuest, isGlobalPlayerQuest, isGlobalNPC, isItemQuest, isSpellQuest, package_name, mob, npcmob);
}
/* Check for Zone export event enable */
if (parse->perl_event_export_settings[event].zone){
ExportZoneVariables(package_name);
}
/* Check for Item export event enable */
if (parse->perl_event_export_settings[event].item){
ExportItemVariables(package_name, mob);
}
/* Check for Event export event enable */
if (parse->perl_event_export_settings[event].event_variables){
ExportEventVariables(package_name, event, objid, data, npcmob, iteminst, mob, extradata, extra_pointers);
}
if(isPlayerQuest || isGlobalPlayerQuest){
return SendCommands(package_name.c_str(), sub_name, 0, mob, mob, nullptr);
@@ -199,8 +215,7 @@ int PerlembParser::EventCommon(QuestEventID event, uint32 objid, const char * da
else if(isItemQuest) {
return SendCommands(package_name.c_str(), sub_name, 0, mob, mob, iteminst);
}
else if(isSpellQuest)
{
else if(isSpellQuest){
if(mob) {
return SendCommands(package_name.c_str(), sub_name, 0, mob, mob, nullptr);
} else {
+1
View File
@@ -75,6 +75,7 @@ public:
virtual std::string GetVar(std::string name);
virtual void ReloadQuests();
virtual uint32 GetIdentifier() { return 0xf8b05c11; }
private:
Embperl *perl;
+4 -2
View File
@@ -51,7 +51,7 @@
#endif
extern Zone *zone;
extern volatile bool ZoneLoaded;
extern volatile bool is_zone_loaded;
extern WorldServer worldserver;
extern NetConnection net;
extern uint32 numclients;
@@ -2350,7 +2350,7 @@ void EntityList::Clear()
void EntityList::UpdateWho(bool iSendFullUpdate)
{
if ((!worldserver.Connected()) || !ZoneLoaded)
if ((!worldserver.Connected()) || !is_zone_loaded)
return;
uint32 tmpNumUpdates = numclients + 5;
ServerPacket* pack = 0;
@@ -2448,6 +2448,8 @@ void EntityList::Depop(bool StartSpawnTimer)
if (pnpc->IsFindable())
UpdateFindableNPCState(pnpc, true);
pnpc->WipeHateList();
pnpc->Depop(StartSpawnTimer);
}
}
+7 -7
View File
@@ -33,7 +33,7 @@ extern Zone* zone;
//this is called whenever we are damaged to process possible fleeing
void Mob::CheckFlee() {
//if were allready fleeing, dont need to check more...
if(flee_mode && curfp)
if(flee_mode && currently_fleeing)
return;
//dont bother if we are immune to fleeing
@@ -101,7 +101,7 @@ void Mob::ProcessFlee()
//When ImmuneToFlee effect fades it will turn fear back on and check if it can still flee.
if (flee_mode && (GetSpecialAbility(IMMUNE_FLEEING) || spellbonuses.ImmuneToFlee) &&
!spellbonuses.IsFeared && !spellbonuses.IsBlind) {
curfp = false;
currently_fleeing = false;
return;
}
@@ -118,7 +118,7 @@ void Mob::ProcessFlee()
//see if we are legitimately feared or blind now
if (!spellbonuses.IsFeared && !spellbonuses.IsBlind) {
//not feared or blind... were done...
curfp = false;
currently_fleeing = false;
return;
}
}
@@ -140,7 +140,7 @@ void Mob::CalculateNewFearpoint()
if(Route.size() > 0)
{
m_FearWalkTarget = glm::vec3(Loc.x, Loc.y, Loc.z);
curfp = true;
currently_fleeing = true;
Log.Out(Logs::Detail, Logs::None, "Feared to node %i (%8.3f, %8.3f, %8.3f)", Node, Loc.x, Loc.y, Loc.z);
return;
@@ -151,7 +151,7 @@ void Mob::CalculateNewFearpoint()
int loop = 0;
float ranx, rany, ranz;
curfp = false;
currently_fleeing = false;
while (loop < 100) //Max 100 tries
{
int ran = 250 - (loop*2);
@@ -164,11 +164,11 @@ void Mob::CalculateNewFearpoint()
float fdist = ranz - GetZ();
if (fdist >= -12 && fdist <= 12 && CheckCoordLosNoZLeaps(GetX(),GetY(),GetZ(),ranx,rany,ranz))
{
curfp = true;
currently_fleeing = true;
break;
}
}
if (curfp)
if (currently_fleeing)
m_FearWalkTarget = glm::vec3(ranx, rany, ranz);
else //Break fear
BuffFadeByEffect(SE_Fear);
+3 -1
View File
@@ -248,7 +248,9 @@ void Client::RefreshGuildInfo()
if((guild_id != OldGuildID) && GuildBanks)
{
ClearGuildBank();
// Unsure about this for RoF+ ... But they don't have that action anymore so fuck it
if (GetClientVersion() < ClientVersion::RoF)
ClearGuildBank();
if(guild_id != GUILD_NONE)
GuildBanks->SendGuildBank(this);
+78 -21
View File
@@ -29,7 +29,7 @@ ZoneGuildManager guild_mgr;
GuildBankManager *GuildBanks;
extern WorldServer worldserver;
extern volatile bool ZoneLoaded;
extern volatile bool is_zone_loaded;
void ZoneGuildManager::SendGuildRefresh(uint32 guild_id, bool name, bool motd, bool rank, bool relation) {
Log.Out(Logs::Detail, Logs::Guilds, "Sending guild refresh for %d to world, changes: name=%d, motd=%d, rank=d, relation=%d", guild_id, name, motd, rank, relation);
@@ -334,7 +334,7 @@ void ZoneGuildManager::ProcessWorldPacket(ServerPacket *pack) {
case ServerOP_GuildRankUpdate:
{
if(ZoneLoaded)
if(is_zone_loaded)
{
if(pack->size != sizeof(ServerGuildRankUpdate_Struct))
{
@@ -388,7 +388,7 @@ void ZoneGuildManager::ProcessWorldPacket(ServerPacket *pack) {
{
ServerGuildMemberUpdate_Struct *sgmus = (ServerGuildMemberUpdate_Struct*)pack->pBuffer;
if(ZoneLoaded)
if(is_zone_loaded)
{
EQApplicationPacket *outapp = new EQApplicationPacket(OP_GuildMemberUpdate, sizeof(GuildMemberUpdate_Struct));
@@ -407,7 +407,7 @@ void ZoneGuildManager::ProcessWorldPacket(ServerPacket *pack) {
break;
}
case ServerOP_OnlineGuildMembersResponse:
if (ZoneLoaded)
if (is_zone_loaded)
{
char *Buffer = (char *)pack->pBuffer;
@@ -443,7 +443,7 @@ void ZoneGuildManager::ProcessWorldPacket(ServerPacket *pack) {
case ServerOP_LFGuildUpdate:
{
if(ZoneLoaded)
if(is_zone_loaded)
{
char GuildName[33];
char Comments[257];
@@ -688,11 +688,68 @@ void GuildBankManager::SendGuildBank(Client *c)
return;
}
auto &guild_bank = *Iterator;
// RoF+ uses a bulk list packet -- This is also how the Action 0 of older clients basically works
if (c->GetClientVersionBit() & BIT_RoFAndLater) {
auto outapp = new EQApplicationPacket(OP_GuildBankItemList, sizeof(GuildBankItemListEntry_Struct) * 240);
for (int i = 0; i < GUILD_BANK_DEPOSIT_AREA_SIZE; ++i) {
const Item_Struct *Item = database.GetItem(guild_bank->Items.DepositArea[i].ItemID);
if (Item) {
outapp->WriteUInt8(1);
outapp->WriteUInt32(guild_bank->Items.DepositArea[i].Permissions);
outapp->WriteString(guild_bank->Items.DepositArea[i].WhoFor);
outapp->WriteString(guild_bank->Items.DepositArea[i].Donator);
outapp->WriteUInt32(Item->ID);
outapp->WriteUInt32(Item->Icon);
if (Item->Stackable) {
outapp->WriteUInt32(guild_bank->Items.DepositArea[i].Quantity);
outapp->WriteUInt8(Item->StackSize == guild_bank->Items.DepositArea[i].Quantity ? 0 : 1);
} else {
outapp->WriteUInt32(1);
outapp->WriteUInt8(0);
}
outapp->WriteUInt8(Item->IsEquipable(c->GetBaseRace(), c->GetBaseClass()) ? 1 : 0);
outapp->WriteString(Item->Name);
} else {
outapp->WriteUInt8(0); // empty
}
}
outapp->SetWritePosition(outapp->GetWritePosition() + 20); // newer clients have 40 deposit slots, keep them 0 for now
for (int i = 0; i < GUILD_BANK_MAIN_AREA_SIZE; ++i) {
const Item_Struct *Item = database.GetItem(guild_bank->Items.MainArea[i].ItemID);
if (Item) {
outapp->WriteUInt8(1);
outapp->WriteUInt32(guild_bank->Items.MainArea[i].Permissions);
outapp->WriteString(guild_bank->Items.MainArea[i].WhoFor);
outapp->WriteString(guild_bank->Items.MainArea[i].Donator);
outapp->WriteUInt32(Item->ID);
outapp->WriteUInt32(Item->Icon);
if (Item->Stackable) {
outapp->WriteUInt32(guild_bank->Items.MainArea[i].Quantity);
outapp->WriteUInt8(Item->StackSize == guild_bank->Items.MainArea[i].Quantity ? 0 : 1);
} else {
outapp->WriteUInt32(1);
outapp->WriteUInt8(0);
}
outapp->WriteUInt8(Item->IsEquipable(c->GetBaseRace(), c->GetBaseClass()) ? 1 : 0);
outapp->WriteString(Item->Name);
} else {
outapp->WriteUInt8(0); // empty
}
}
outapp->size = outapp->GetWritePosition(); // truncate to used size
c->FastQueuePacket(&outapp);
return;
}
for(int i = 0; i < GUILD_BANK_DEPOSIT_AREA_SIZE; ++i)
{
if((*Iterator)->Items.DepositArea[i].ItemID > 0)
if(guild_bank->Items.DepositArea[i].ItemID > 0)
{
const Item_Struct *Item = database.GetItem((*Iterator)->Items.DepositArea[i].ItemID);
const Item_Struct *Item = database.GetItem(guild_bank->Items.DepositArea[i].ItemID);
if(!Item)
continue;
@@ -703,22 +760,22 @@ void GuildBankManager::SendGuildBank(Client *c)
if(!Item->Stackable)
gbius->Init(GuildBankItemUpdate, 1, i, GuildBankDepositArea, 1, Item->ID, Item->Icon, 1,
(*Iterator)->Items.DepositArea[i].Permissions, 0, 0);
guild_bank->Items.DepositArea[i].Permissions, 0, 0);
else
{
if((*Iterator)->Items.DepositArea[i].Quantity == Item->StackSize)
if(guild_bank->Items.DepositArea[i].Quantity == Item->StackSize)
gbius->Init(GuildBankItemUpdate, 1, i, GuildBankDepositArea, 1, Item->ID, Item->Icon,
(*Iterator)->Items.DepositArea[i].Quantity, (*Iterator)->Items.DepositArea[i].Permissions, 0, 0);
guild_bank->Items.DepositArea[i].Quantity, guild_bank->Items.DepositArea[i].Permissions, 0, 0);
else
gbius->Init(GuildBankItemUpdate, 1, i, GuildBankDepositArea, 1, Item->ID, Item->Icon,
(*Iterator)->Items.DepositArea[i].Quantity, (*Iterator)->Items.DepositArea[i].Permissions, 1, 0);
guild_bank->Items.DepositArea[i].Quantity, guild_bank->Items.DepositArea[i].Permissions, 1, 0);
}
strn0cpy(gbius->ItemName, Item->Name, sizeof(gbius->ItemName));
strn0cpy(gbius->Donator, (*Iterator)->Items.DepositArea[i].Donator, sizeof(gbius->Donator));
strn0cpy(gbius->Donator, guild_bank->Items.DepositArea[i].Donator, sizeof(gbius->Donator));
strn0cpy(gbius->WhoFor, (*Iterator)->Items.DepositArea[i].WhoFor, sizeof(gbius->WhoFor));
strn0cpy(gbius->WhoFor, guild_bank->Items.DepositArea[i].WhoFor, sizeof(gbius->WhoFor));
c->FastQueuePacket(&outapp);
}
@@ -726,9 +783,9 @@ void GuildBankManager::SendGuildBank(Client *c)
for(int i = 0; i < GUILD_BANK_MAIN_AREA_SIZE; ++i)
{
if((*Iterator)->Items.MainArea[i].ItemID > 0)
if(guild_bank->Items.MainArea[i].ItemID > 0)
{
const Item_Struct *Item = database.GetItem((*Iterator)->Items.MainArea[i].ItemID);
const Item_Struct *Item = database.GetItem(guild_bank->Items.MainArea[i].ItemID);
if(!Item)
continue;
@@ -741,22 +798,22 @@ void GuildBankManager::SendGuildBank(Client *c)
if(!Item->Stackable)
gbius->Init(GuildBankItemUpdate, 1, i, GuildBankMainArea, 1, Item->ID, Item->Icon, 1,
(*Iterator)->Items.MainArea[i].Permissions, 0, Useable);
guild_bank->Items.MainArea[i].Permissions, 0, Useable);
else
{
if((*Iterator)->Items.MainArea[i].Quantity == Item->StackSize)
if(guild_bank->Items.MainArea[i].Quantity == Item->StackSize)
gbius->Init(GuildBankItemUpdate, 1, i, GuildBankMainArea, 1, Item->ID, Item->Icon,
(*Iterator)->Items.MainArea[i].Quantity, (*Iterator)->Items.MainArea[i].Permissions, 0, Useable);
guild_bank->Items.MainArea[i].Quantity, guild_bank->Items.MainArea[i].Permissions, 0, Useable);
else
gbius->Init(GuildBankItemUpdate, 1, i, GuildBankMainArea, 1, Item->ID, Item->Icon,
(*Iterator)->Items.MainArea[i].Quantity, (*Iterator)->Items.MainArea[i].Permissions, 1, Useable);
guild_bank->Items.MainArea[i].Quantity, guild_bank->Items.MainArea[i].Permissions, 1, Useable);
}
strn0cpy(gbius->ItemName, Item->Name, sizeof(gbius->ItemName));
strn0cpy(gbius->Donator, (*Iterator)->Items.MainArea[i].Donator, sizeof(gbius->Donator));
strn0cpy(gbius->Donator, guild_bank->Items.MainArea[i].Donator, sizeof(gbius->Donator));
strn0cpy(gbius->WhoFor, (*Iterator)->Items.MainArea[i].WhoFor, sizeof(gbius->WhoFor));
strn0cpy(gbius->WhoFor, guild_bank->Items.MainArea[i].WhoFor, sizeof(gbius->WhoFor));
c->FastQueuePacket(&outapp);
}
+7 -7
View File
@@ -18,7 +18,7 @@
#include "../common/string_util.h"
#include "../common/rulesys.h"
extern volatile bool ZoneLoaded;
extern volatile bool is_zone_loaded;
Merc::Merc(const NPCType* d, float x, float y, float z, float heading)
: NPC(d, nullptr, glm::vec4(x, y, z, heading), 0, false), endupkeep_timer(1000), rest_timer(1), confidence_timer(6000), check_target_timer(2000)
@@ -1428,7 +1428,7 @@ void Merc::AI_Process() {
if(RuleB(Combat, EnableFearPathing)) {
CalculateNewFearpoint();
if(curfp) {
if(currently_fleeing) {
return;
}
}
@@ -1500,7 +1500,7 @@ void Merc::AI_Process() {
}
}
if(AImovement_timer->Check())
if(AI_movement_timer->Check())
{
if(!IsMoving() && GetClass() == ROGUE && !BehindMob(GetTarget(), GetX(), GetY()))
{
@@ -1645,7 +1645,7 @@ void Merc::AI_Process() {
AI_PursueCastCheck();
}
if (AImovement_timer->Check())
if (AI_movement_timer->Check())
{
if(!IsRooted()) {
Log.Out(Logs::Detail, Logs::AI, "Pursuing %s while engaged.", GetTarget()->GetCleanName());
@@ -1687,7 +1687,7 @@ void Merc::AI_Process() {
if(!check_target_timer.Enabled())
check_target_timer.Start(2000, false);
if(!IsMoving() && AIthink_timer->Check() && !spellend_timer.Enabled())
if(!IsMoving() && AI_think_timer->Check() && !spellend_timer.Enabled())
{
//TODO: Implement passive stances.
//if(GetStance() != MercStancePassive) {
@@ -1698,7 +1698,7 @@ void Merc::AI_Process() {
}
}
if(AImovement_timer->Check())
if(AI_movement_timer->Check())
{
if(GetFollowID())
{
@@ -5777,7 +5777,7 @@ bool Merc::RemoveMercFromGroup(Merc* merc, Group* group) {
{
merc->SetFollowID(0);
if (group->GroupCount() <= 2 && merc->GetGroup() == group && ZoneLoaded)
if (group->GroupCount() <= 2 && merc->GetGroup() == group && is_zone_loaded)
{
group->DisbandGroup();
}
+1
View File
@@ -192,6 +192,7 @@ public:
virtual void ScaleStats(int scalepercent, bool setmax = false);
virtual void CalcBonuses();
int32 GetEndurance() const {return cur_end;} //This gets our current endurance
inline uint8 GetEndurancePercent() { return (uint8)((float)cur_end / (float)max_end * 100.0f); }
inline virtual int32 GetAC() const { return AC; }
inline virtual int32 GetATK() const { return ATK; }
inline virtual int32 GetATKBonus() const { return itembonuses.ATK + spellbonuses.ATK; }
+5 -9
View File
@@ -113,7 +113,7 @@ Mob::Mob(const char* in_name,
targeted = 0;
tar_ndx=0;
tar_vector=0;
curfp = false;
currently_fleeing = false;
AI_Init();
SetMoving(false);
@@ -371,7 +371,7 @@ Mob::Mob(const char* in_name,
follow=0;
follow_dist = 100; // Default Distance for Follow
flee_mode = false;
curfp = false;
currently_fleeing = false;
flee_timer.Start();
permarooted = (runspeed > 0) ? false : true;
@@ -503,13 +503,9 @@ void Mob::SetInvisible(uint8 state)
SendAppearancePacket(AT_Invis, invisible);
// Invis and hide breaks charms
if ((this->GetPetType() == petCharmed) && (invisible || hidden || improved_hidden))
{
Mob* formerpet = this->GetPet();
if(formerpet)
formerpet->BuffFadeByEffect(SE_Charm);
}
auto formerpet = GetPet();
if (formerpet && formerpet->GetPetType() == petCharmed && (invisible || hidden || improved_hidden))
formerpet->BuffFadeByEffect(SE_Charm);
}
//check to see if `this` is invisible to `other`
+10 -9
View File
@@ -925,8 +925,8 @@ public:
virtual FACTION_VALUE GetReverseFactionCon(Mob* iOther) { return FACTION_INDIFFERENT; }
inline bool IsTrackable() const { return(trackable); }
Timer* GetAIThinkTimer() { return AIthink_timer.get(); }
Timer* GetAIMovementTimer() { return AImovement_timer.get(); }
Timer* GetAIThinkTimer() { return AI_think_timer.get(); }
Timer* GetAIMovementTimer() { return AI_movement_timer.get(); }
Timer GetAttackTimer() { return attack_timer; }
Timer GetAttackDWTimer() { return attack_dw_timer; }
inline bool IsFindable() { return findable; }
@@ -1254,14 +1254,15 @@ protected:
uint32 maxLastFightingDelayMoving;
float pAggroRange;
float pAssistRange;
std::unique_ptr<Timer> AIthink_timer;
std::unique_ptr<Timer> AImovement_timer;
std::unique_ptr<Timer> AItarget_check_timer;
std::unique_ptr<Timer> AI_think_timer;
std::unique_ptr<Timer> AI_movement_timer;
std::unique_ptr<Timer> AI_target_check_timer;
bool movetimercompleted;
bool permarooted;
std::unique_ptr<Timer> AIscanarea_timer;
std::unique_ptr<Timer> AIwalking_timer;
std::unique_ptr<Timer> AIfeignremember_timer;
std::unique_ptr<Timer> AI_scan_area_timer;
std::unique_ptr<Timer> AI_walking_timer;
std::unique_ptr<Timer> AI_feign_remember_timer;
std::unique_ptr<Timer> AI_check_signal_timer;
uint32 pLastFightingDelayMoving;
HateList hate_list;
std::set<uint32> feign_memory_list;
@@ -1295,7 +1296,7 @@ protected:
int patrol;
glm::vec3 m_FearWalkTarget;
bool curfp;
bool currently_fleeing;
// Pathing
//
+60 -50
View File
@@ -423,12 +423,14 @@ bool EntityList::AICheckCloseBeneficialSpells(NPC* caster, uint8 iChance, float
void Mob::AI_Init()
{
pAIControlled = false;
AIthink_timer.reset(nullptr);
AIwalking_timer.reset(nullptr);
AImovement_timer.reset(nullptr);
AItarget_check_timer.reset(nullptr);
AIfeignremember_timer.reset(nullptr);
AIscanarea_timer.reset(nullptr);
AI_think_timer.reset(nullptr);
AI_walking_timer.reset(nullptr);
AI_movement_timer.reset(nullptr);
AI_target_check_timer.reset(nullptr);
AI_feign_remember_timer.reset(nullptr);
AI_scan_area_timer.reset(nullptr);
AI_check_signal_timer.reset(nullptr);
minLastFightingDelayMoving = RuleI(NPC, LastFightingDelayMovingMin);
maxLastFightingDelayMoving = RuleI(NPC, LastFightingDelayMovingMax);
@@ -472,16 +474,18 @@ void Mob::AI_Start(uint32 iMoveDelay) {
pLastFightingDelayMoving = 0;
pAIControlled = true;
AIthink_timer = std::unique_ptr<Timer>(new Timer(AIthink_duration));
AIthink_timer->Trigger();
AIwalking_timer = std::unique_ptr<Timer>(new Timer(0));
AImovement_timer = std::unique_ptr<Timer>(new Timer(AImovement_duration));
AItarget_check_timer = std::unique_ptr<Timer>(new Timer(AItarget_check_duration));
AIfeignremember_timer = std::unique_ptr<Timer>(new Timer(AIfeignremember_delay));
AIscanarea_timer = std::unique_ptr<Timer>(new Timer(AIscanarea_delay));
AI_think_timer = std::unique_ptr<Timer>(new Timer(AIthink_duration));
AI_think_timer->Trigger();
AI_walking_timer = std::unique_ptr<Timer>(new Timer(0));
AI_movement_timer = std::unique_ptr<Timer>(new Timer(AImovement_duration));
AI_target_check_timer = std::unique_ptr<Timer>(new Timer(AItarget_check_duration));
AI_feign_remember_timer = std::unique_ptr<Timer>(new Timer(AIfeignremember_delay));
AI_scan_area_timer = std::unique_ptr<Timer>(new Timer(RandomTimer(RuleI(NPC, NPCToNPCAggroTimerMin), RuleI(NPC, NPCToNPCAggroTimerMax))));
AI_check_signal_timer = std::unique_ptr<Timer>(new Timer(AI_check_signal_timer_delay));
#ifdef REVERSE_AGGRO
if(IsNPC() && !CastToNPC()->WillAggroNPCs())
AIscanarea_timer->Disable();
AI_scan_area_timer->Disable();
#endif
if (GetAggroRange() == 0)
@@ -538,12 +542,13 @@ void Mob::AI_Stop() {
pAIControlled = false;
AIthink_timer.reset(nullptr);
AIwalking_timer.reset(nullptr);
AImovement_timer.reset(nullptr);
AItarget_check_timer.reset(nullptr);
AIscanarea_timer.reset(nullptr);
AIfeignremember_timer.reset(nullptr);
AI_think_timer.reset(nullptr);
AI_walking_timer.reset(nullptr);
AI_movement_timer.reset(nullptr);
AI_target_check_timer.reset(nullptr);
AI_scan_area_timer.reset(nullptr);
AI_feign_remember_timer.reset(nullptr);
AI_check_signal_timer.reset(nullptr);
hate_list.WipeHateList();
}
@@ -725,7 +730,7 @@ void Client::AI_Process()
if (!IsAIControlled())
return;
if (!(AIthink_timer->Check() || attack_timer.Check(false)))
if (!(AI_think_timer->Check() || attack_timer.Check(false)))
return;
if (IsCasting())
@@ -759,7 +764,7 @@ void Client::AI_Process()
}
if(RuleB(Combat, EnableFearPathing)){
if(curfp) {
if(currently_fleeing) {
if(IsRooted()) {
//make sure everybody knows were not moving, for appearance sake
if(IsMoving())
@@ -771,7 +776,7 @@ void Client::AI_Process()
//continue on to attack code, ensuring that we execute the engaged code
engaged = true;
} else {
if(AImovement_timer->Check()) {
if(AI_movement_timer->Check()) {
int speed = GetFearSpeed();
animation = speed;
speed *= 2;
@@ -808,7 +813,7 @@ void Client::AI_Process()
SetTarget(hate_list.GetClosestEntOnHateList(this));
else
{
if(AItarget_check_timer->Check())
if(AI_target_check_timer->Check())
{
SetTarget(hate_list.GetEntWithMostHateOnList(this));
}
@@ -832,7 +837,7 @@ void Client::AI_Process()
DoClassAttacks(GetTarget());
}
if (AImovement_timer->Check()) {
if (AI_movement_timer->Check()) {
if (CalculateHeadingToTarget(GetTarget()->GetX(), GetTarget()->GetY()) !=
m_Position.w) {
SetHeading(CalculateHeadingToTarget(GetTarget()->GetX(), GetTarget()->GetY()));
@@ -858,7 +863,7 @@ void Client::AI_Process()
} else {
if(!IsRooted())
{
if(AImovement_timer->Check())
if(AI_movement_timer->Check())
{
int newspeed = GetRunspeed();
animation = newspeed;
@@ -889,7 +894,7 @@ void Client::AI_Process()
}
else
{
if(AIfeignremember_timer->Check()) {
if(AI_feign_remember_timer->Check()) {
std::set<uint32>::iterator RememberedCharID;
RememberedCharID = feign_memory_list.begin();
while (RememberedCharID != feign_memory_list.end()) {
@@ -917,7 +922,7 @@ void Client::AI_Process()
float dist = DistanceSquared(m_Position, owner->GetPosition());
if (dist >= 400)
{
if(AImovement_timer->Check())
if(AI_movement_timer->Check())
{
int nspeed = (dist >= 5625 ? GetRunspeed() : GetWalkspeed());
animation = nspeed;
@@ -943,7 +948,7 @@ void Mob::AI_Process() {
if (!IsAIControlled())
return;
if (!(AIthink_timer->Check() || attack_timer.Check(false)))
if (!(AI_think_timer->Check() || attack_timer.Check(false)))
return;
if (IsCasting())
@@ -955,7 +960,7 @@ void Mob::AI_Process() {
// Begin: Additions for Wiz Fear Code
//
if(RuleB(Combat, EnableFearPathing)){
if(curfp) {
if(currently_fleeing) {
if(IsRooted() || (IsBlind() && CombatRange(hate_list.GetClosestEntOnHateList(this)))) {
//make sure everybody knows were not moving, for appearance sake
if(IsMoving())
@@ -968,7 +973,7 @@ void Mob::AI_Process() {
//continue on to attack code, ensuring that we execute the engaged code
engaged = true;
} else {
if(AImovement_timer->Check()) {
if(AI_movement_timer->Check()) {
// Check if we have reached the last fear point
if ((std::abs(GetX() - m_FearWalkTarget.x) < 0.1) &&
(std::abs(GetY() - m_FearWalkTarget.y) < 0.1)) {
@@ -998,7 +1003,7 @@ void Mob::AI_Process() {
}
// trigger EVENT_SIGNAL if required
if(IsNPC()) {
if (AI_check_signal_timer->Check() && IsNPC()) {
CastToNPC()->CheckSignal();
}
@@ -1012,7 +1017,7 @@ void Mob::AI_Process() {
SetTarget(hate_list.GetClosestEntOnHateList(this));
else
{
if(AItarget_check_timer->Check())
if(AI_target_check_timer->Check())
{
if (IsFocused()) {
if (!target) {
@@ -1074,7 +1079,7 @@ void Mob::AI_Process() {
if (is_combat_range)
{
if (AImovement_timer->Check())
if (AI_movement_timer->Check())
{
if(CalculateHeadingToTarget(GetTarget()->GetX(), GetTarget()->GetY()) != m_Position.w)
{
@@ -1268,7 +1273,7 @@ void Mob::AI_Process() {
WipeHateList();
Heal();
BuffFadeAll();
AIwalking_timer->Start(100);
AI_walking_timer->Start(100);
pLastFightingDelayMoving = Timer::GetCurrentTime();
return;
} else if(tar != nullptr) {
@@ -1290,7 +1295,7 @@ void Mob::AI_Process() {
if(AI_PursueCastCheck()){
//we did something, so do not process movement.
}
else if (AImovement_timer->Check())
else if (AI_movement_timer->Check())
{
if(!IsRooted()) {
Log.Out(Logs::Detail, Logs::AI, "Pursuing %s while engaged.", target->GetName());
@@ -1323,7 +1328,7 @@ void Mob::AI_Process() {
{
if (m_PlayerState & static_cast<uint32>(PlayerState::Aggressive))
SendRemovePlayerState(PlayerState::Aggressive);
if(AIfeignremember_timer->Check()) {
if(AI_feign_remember_timer->Check()) {
// 6/14/06
// Improved Feign Death Memory
// check to see if any of our previous feigned targets have gotten up.
@@ -1348,7 +1353,7 @@ void Mob::AI_Process() {
{
//we processed a spell action, so do nothing else.
}
else if (AIscanarea_timer->Check())
else if (AI_scan_area_timer->Check())
{
/*
* This is where NPCs look around to see if they want to attack anybody.
@@ -1359,11 +1364,16 @@ void Mob::AI_Process() {
*
*/
Mob* tmptar = entity_list.AICheckCloseAggro(this, GetAggroRange(), GetAssistRange());
if (tmptar)
AddToHateList(tmptar);
Mob* temp_target = entity_list.AICheckCloseAggro(this, GetAggroRange(), GetAssistRange());
if (temp_target){
AddToHateList(temp_target);
}
AI_scan_area_timer->Disable();
AI_scan_area_timer->Start(RandomTimer(RuleI(NPC, NPCToNPCAggroTimerMin), RuleI(NPC, NPCToNPCAggroTimerMax)), false);
}
else if (AImovement_timer->Check() && !IsRooted())
else if (AI_movement_timer->Check() && !IsRooted())
{
if (IsPet())
{
@@ -1534,10 +1544,10 @@ void NPC::AI_DoMovement() {
}
else if (roamer)
{
if (AIwalking_timer->Check())
if (AI_walking_timer->Check())
{
movetimercompleted=true;
AIwalking_timer->Disable();
AI_walking_timer->Disable();
}
@@ -1547,7 +1557,7 @@ void NPC::AI_DoMovement() {
if (movetimercompleted==true) { // time to pause at wp is over
AI_SetupNextWaypoint();
} // endif (movetimercompleted==true)
else if (!(AIwalking_timer->Enabled()))
else if (!(AI_walking_timer->Enabled()))
{ // currently moving
bool doMove = true;
if (m_CurrentWayPoint.x == GetX() && m_CurrentWayPoint.y == GetY())
@@ -1568,7 +1578,7 @@ void NPC::AI_DoMovement() {
sprintf(temp, "%d", cur_wp);
parse->EventNPC(EVENT_WAYPOINT_ARRIVE, CastToNPC(), nullptr, temp, 0);
// start moving directly to next waypoint if we're at a 0 pause waypoint and we didn't get quest halted.
if (!AIwalking_timer->Enabled())
if (!AI_walking_timer->Enabled())
AI_SetupNextWaypoint();
else
doMove = false;
@@ -1759,7 +1769,7 @@ void Mob::AI_Event_Engaged(Mob* attacker, bool iYellForHelp) {
void Mob::AI_Event_NoLongerEngaged() {
if (!IsAIControlled())
return;
this->AIwalking_timer->Start(RandomTimer(3000,20000));
this->AI_walking_timer->Start(RandomTimer(3000,20000));
pLastFightingDelayMoving = Timer::GetCurrentTime();
if (minLastFightingDelayMoving == maxLastFightingDelayMoving)
pLastFightingDelayMoving += minLastFightingDelayMoving;
@@ -1856,15 +1866,15 @@ bool NPC::AI_PursueCastCheck() {
bool NPC::AI_IdleCastCheck() {
if (AIautocastspell_timer->Check(false)) {
#if MobAI_DEBUG_Spells >= 25
std::cout << "Non-Engaged autocast check triggered: " << this->GetName() << std::endl;
#endif
AIautocastspell_timer->Disable(); //prevent the timer from going off AGAIN while we are casting.
if (!AICastSpell(this, AISpellVar.idle_beneficial_chance, SpellType_Heal | SpellType_Buff | SpellType_Pet)) {
if(!entity_list.AICheckCloseBeneficialSpells(this, 33, MobAISpellRange, SpellType_Heal | SpellType_Buff)) {
//if we didnt cast any spells, our autocast timer just resets to the
//last duration it was set to... try to put up a more reasonable timer...
AIautocastspell_timer->Start(RandomTimer(AISpellVar.idle_no_sp_recast_min, AISpellVar.idle_no_sp_recast_max), false);
Log.Out(Logs::Moderate, Logs::Spells, "Triggering AI_IdleCastCheck :: Mob %s - Min : %u Max : %u", this->GetCleanName(), AISpellVar.idle_no_sp_recast_min, AISpellVar.idle_no_sp_recast_max);
} //else, spell casting finishing will reset the timer.
} //else, spell casting finishing will reset the timer.
return(true);
+12 -7
View File
@@ -84,7 +84,7 @@
#endif
volatile bool RunLoops = true;
extern volatile bool ZoneLoaded;
extern volatile bool is_zone_loaded;
TimeoutManager timeout_manager;
NetConnection net;
@@ -110,6 +110,7 @@ extern void MapOpcodes();
int main(int argc, char** argv) {
RegisterExecutablePlatform(ExePlatformZone);
Log.LoadLogSettingsDefaults();
set_exception_handler();
QServ = new QueryServ;
@@ -339,6 +340,10 @@ int main(int argc, char** argv) {
#ifdef EMBPERL
PerlembParser *perl_parser = new PerlembParser();
parse->RegisterQuestInterface(perl_parser, "pl");
/* Load Perl Event Export Settings */
parse->LoadPerlEventExportSettings(parse->perl_event_export_settings);
#endif
//now we have our parser, load the quests
@@ -388,10 +393,10 @@ int main(int argc, char** argv) {
worldserver.Process();
if (!eqsf.IsOpen() && Config->ZonePort!=0) {
Log.Out(Logs::General, Logs::Zone_Server, "Starting EQ Network server on port %d",Config->ZonePort);
if (!eqsf.IsOpen() && Config->ZonePort != 0) {
Log.Out(Logs::General, Logs::Zone_Server, "Starting EQ Network server on port %d", Config->ZonePort);
if (!eqsf.Open(Config->ZonePort)) {
Log.Out(Logs::General, Logs::Error, "Failed to open port %d",Config->ZonePort);
Log.Out(Logs::General, Logs::Error, "Failed to open port %d", Config->ZonePort);
ZoneConfig::SetZonePort(0);
worldserver.Disconnect();
worldwasconnected = false;
@@ -405,7 +410,7 @@ int main(int argc, char** argv) {
//structures and opcodes for that patch.
struct in_addr in;
in.s_addr = eqss->GetRemoteIP();
Log.Out(Logs::Detail, Logs::World_Server, "New connection from %s:%d", inet_ntoa(in),ntohs(eqss->GetRemotePort()));
Log.Out(Logs::Detail, Logs::World_Server, "New connection from %s:%d", inet_ntoa(in), ntohs(eqss->GetRemotePort()));
stream_identifier.AddStream(eqss); //takes the stream
}
@@ -437,12 +442,12 @@ int main(int argc, char** argv) {
worldwasconnected = true;
}
else {
if (worldwasconnected && ZoneLoaded)
if (worldwasconnected && is_zone_loaded)
entity_list.ChannelMessageFromWorld(0, 0, 6, 0, 0, "WARNING: World server connection lost");
worldwasconnected = false;
}
if (ZoneLoaded && zoneupdate_timer.Check()) {
if (is_zone_loaded && zoneupdate_timer.Check()) {
{
if(net.group_timer.Enabled() && net.group_timer.Check())
entity_list.GroupProcess();
+2 -2
View File
@@ -53,7 +53,7 @@
#endif
extern Zone* zone;
extern volatile bool ZoneLoaded;
extern volatile bool is_zone_loaded;
extern EntityList entity_list;
NPC::NPC(const NPCType* d, Spawn2* in_respawn, const glm::vec4& position, int iflymode, bool IsCorpse)
@@ -605,7 +605,7 @@ bool NPC::Process()
parse->EventNPC(EVENT_TICK, this, nullptr, "", 0);
BuffProcess();
if(curfp)
if(currently_fleeing)
ProcessFlee();
uint32 bonus = 0;
+39
View File
@@ -1032,3 +1032,42 @@ int QuestParserCollection::DispatchEventSpell(QuestEventID evt, NPC* npc, Client
}
return ret;
}
void QuestParserCollection::LoadPerlEventExportSettings(PerlEventExportSettings* perl_event_export_settings) {
Log.Out(Logs::General, Logs::Zone_Server, "Loading Perl Event Export Settings...");
/* Write Defaults First (All Enabled) */
for (int i = 0; i < _LargestEventID; i++){
perl_event_export_settings[i].qglobals = 1;
perl_event_export_settings[i].mob = 1;
perl_event_export_settings[i].zone = 1;
perl_event_export_settings[i].item = 1;
perl_event_export_settings[i].event_variables = 1;
}
std::string query =
"SELECT "
"event_id, "
"event_description, "
"export_qglobals, "
"export_mob, "
"export_zone, "
"export_item, "
"export_event "
"FROM "
"perl_event_export_settings "
"ORDER BY event_id";
int event_id = 0;
auto results = database.QueryDatabase(query);
for (auto row = results.begin(); row != results.end(); ++row) {
event_id = atoi(row[0]);
perl_event_export_settings[event_id].qglobals = atoi(row[2]);
perl_event_export_settings[event_id].mob = atoi(row[3]);
perl_event_export_settings[event_id].zone = atoi(row[4]);
perl_event_export_settings[event_id].item = atoi(row[5]);
perl_event_export_settings[event_id].event_variables = atoi(row[6]);
}
}
+21
View File
@@ -77,6 +77,27 @@ public:
void GetErrors(std::list<std::string> &err);
/*
Internally used memory reference for all Perl Event Export Settings
Some exports are very taxing on CPU given how much an event is called.
These are loaded via DB and have defaults loaded in PerlEventExportSettingsDefaults.
Database loaded via Database::LoadPerlEventExportSettings(log_settings)
*/
struct PerlEventExportSettings {
uint8 qglobals;
uint8 mob;
uint8 zone;
uint8 item;
uint8 event_variables;
};
PerlEventExportSettings perl_event_export_settings[_LargestEventID];
void LoadPerlEventExportSettings(PerlEventExportSettings* perl_event_export_settings);
private:
bool HasQuestSubLocal(uint32 npcid, QuestEventID evt);
bool HasQuestSubGlobal(QuestEventID evt);
+106
View File
@@ -351,6 +351,112 @@ void Spawn2::DeathReset(bool realdeath)
}
}
bool ZoneDatabase::PopulateZoneSpawnListClose(uint32 zoneid, LinkedList<Spawn2*> &spawn2_list, int16 version, const glm::vec4& client_position, uint32 repop_distance)
{
std::unordered_map<uint32, uint32> spawn_times;
float mob_distance = 0;
timeval tv;
gettimeofday(&tv, nullptr);
/* Bulk Load NPC Types Data into the cache */
database.LoadNPCTypesData(0, true);
std::string spawn_query = StringFormat(
"SELECT "
"respawn_times.id, "
"respawn_times.`start`, "
"respawn_times.duration "
"FROM "
"respawn_times "
"WHERE instance_id = %u",
zone->GetInstanceID()
);
auto results = QueryDatabase(spawn_query);
for (auto row = results.begin(); row != results.end(); ++row) {
uint32 start_duration = atoi(row[1]) > 0 ? atoi(row[1]) : 0;
uint32 end_duration = atoi(row[2]) > 0 ? atoi(row[2]) : 0;
/* Our current time was expired */
if ((start_duration + end_duration) <= tv.tv_sec) {
spawn_times[atoi(row[0])] = 0;
}
/* We still have time left on this timer */
else {
spawn_times[atoi(row[0])] = ((start_duration + end_duration) - tv.tv_sec) * 1000;
}
}
const char *zone_name = database.GetZoneName(zoneid);
std::string query = StringFormat(
"SELECT "
"id, "
"spawngroupID, "
"x, "
"y, "
"z, "
"heading, "
"respawntime, "
"variance, "
"pathgrid, "
"_condition, "
"cond_value, "
"enabled, "
"animation "
"FROM "
"spawn2 "
"WHERE zone = '%s' AND version = %u",
zone_name,
version
);
results = QueryDatabase(query);
if (!results.Success()) {
return false;
}
for (auto row = results.begin(); row != results.end(); ++row) {
uint32 spawn_time_left = 0;
Spawn2* new_spawn = 0;
bool perl_enabled = atoi(row[11]) == 1 ? true : false;
if (spawn_times.count(atoi(row[0])) != 0)
spawn_time_left = spawn_times[atoi(row[0])];
glm::vec4 point;
point.x = atof(row[2]);
point.y = atof(row[3]);
mob_distance = DistanceNoZ(client_position, point);
if (mob_distance > repop_distance)
continue;
new_spawn = new Spawn2( //
atoi(row[0]), // uint32 in_spawn2_id
atoi(row[1]), // uint32 spawngroup_id
atof(row[2]), // float in_x
atof(row[3]), // float in_y
atof(row[4]), // float in_z
atof(row[5]), // float in_heading
atoi(row[6]), // uint32 respawn
atoi(row[7]), // uint32 variance
spawn_time_left, // uint32 timeleft
atoi(row[8]), // uint32 grid
atoi(row[9]), // uint16 in_cond_id
atoi(row[10]), // int16 in_min_value
perl_enabled, // bool in_enabled
(EmuAppearance)atoi(row[12]) // EmuAppearance anim
);
spawn2_list.Insert(new_spawn);
}
return true;
}
bool ZoneDatabase::PopulateZoneSpawnList(uint32 zoneid, LinkedList<Spawn2*> &spawn2_list, int16 version, uint32 repopdelay) {
std::unordered_map<uint32, uint32> spawn_times;
+32 -11
View File
@@ -38,7 +38,7 @@
extern Zone* zone;
extern volatile bool ZoneLoaded;
extern volatile bool is_zone_loaded;
extern WorldServer worldserver;
@@ -283,9 +283,13 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
//do any AAs apply to these spells?
if(dmg < 0) {
if (!PassCastRestriction(false, spells[spell_id].base2[i], true))
break;
dmg = -dmg;
Damage(caster, dmg, spell_id, spell.skill, false, buffslot, false);
} else {
if (!PassCastRestriction(false, spells[spell_id].base2[i], false))
break;
HealDamage(dmg, caster);
}
break;
@@ -864,7 +868,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
}
CalculateNewFearpoint();
if(curfp)
if(currently_fleeing)
{
break;
}
@@ -3429,6 +3433,8 @@ void Mob::DoBuffTic(const Buffs_Struct &buff, int slot, Mob *caster)
switch (effect) {
case SE_CurrentHP: {
if (!PassCastRestriction(false, spells[buff.spellid].base2[i], true))
break;
effect_value = CalcSpellEffectValue(buff.spellid, i, buff.casterlevel, buff.instrument_mod,
caster, buff.ticsremaining);
// Handle client cast DOTs here.
@@ -3944,8 +3950,8 @@ void Mob::BuffFadeBySlot(int slot, bool iRecalcBonuses)
}
case SE_Blind:
if (curfp && !FindType(SE_Fear))
curfp = false;
if (currently_fleeing && !FindType(SE_Fear))
currently_fleeing = false;
break;
case SE_Fear:
@@ -3958,8 +3964,8 @@ void Mob::BuffFadeBySlot(int slot, bool iRecalcBonuses)
CastToClient()->AI_Stop();
}
if(curfp) {
curfp = false;
if(currently_fleeing) {
currently_fleeing = false;
break;
}
}
@@ -3974,7 +3980,7 @@ void Mob::BuffFadeBySlot(int slot, bool iRecalcBonuses)
{
if(RuleB(Combat, EnableFearPathing)){
if(flee_mode) {
curfp = true;
currently_fleeing = true;
CheckFlee();
break;
}
@@ -6224,16 +6230,17 @@ bool Mob::PassCastRestriction(bool UseCastRestriction, int16 value, bool IsDama
Range 410 - 411 : UNKOWN
Range 500 - 599 : Heal if HP less than a specified value
Range 600 - 699 : Limit to Body Type [base2 - 600 = Body]
Range 700 : UNKNOWN
Range 700 : NPC only -- from patch notes "Wizard - Arcane Fusion no longer deals damage to non-NPC targets. This should ensure that wizards who fail their Bucolic Gambit are slightly less likely to annihilate themselves."
Range 701 : NOT PET
Range 800 : UKNOWN
Range 818 - 819 : If Undead/If Not Undead
Range 820 - 822 : UKNOWN
Range 835 : Unknown *not implemented
Range 836 - 837 : Progression Server / Live Server *not implemented
Range 839 : Unknown *not implemented
Range 836 - 837 : Progression Server / Live Server *not fully implemented
Range 839 : Progression Server and GoD released -- broken until Oct 21 2015 on live *not fully implemented
Range 842 - 844 : Humaniod lv MAX ((842 - 800) * 2)
Range 845 - 847 : UNKNOWN
Range 860 - 871 : Humanoid lv MAX 860 = 90, 871 = 104 *not implemented
Range 10000 - 11000 : Limit to Race [base2 - 10000 = Race] (*Not on live: Too useful a function to not implement)
THIS IS A WORK IN PROGRESS
*/
@@ -6387,6 +6394,11 @@ bool Mob::PassCastRestriction(bool UseCastRestriction, int16 value, bool IsDama
return true;
break;
case 700:
if (IsNPC())
return true;
break;
case 701:
if (!IsPet())
return true;
@@ -6402,6 +6414,15 @@ bool Mob::PassCastRestriction(bool UseCastRestriction, int16 value, bool IsDama
return true;
break;
case 836:
return true; // todo implement progression flag assume not progression for now
case 837:
return false; // todo implement progression flag assume not progression for now
case 839:
return true; // todo implement progression flag assume not progression for now, this one is a check if GoD is live
case 842:
if (GetBodyType() == BT_Humanoid && GetLevel() <= 84)
return true;
@@ -6789,4 +6810,4 @@ void Client::BreakFeignDeathWhenCastOn(bool IsResisted)
SetFeigned(false);
Message_StringID(MT_SpellFailure,FD_CAST_ON);
}
}
}
+4 -2
View File
@@ -101,7 +101,7 @@ Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.org)
extern Zone* zone;
extern volatile bool ZoneLoaded;
extern volatile bool is_zone_loaded;
extern WorldServer worldserver;
// this is run constantly for every mob
@@ -2267,7 +2267,9 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, uint16 slot, uint16
}
}
// one may want to check if this is a disc or not, but we actually don't, there are non disc stuff that have end cost
if (spells[spell_id].EndurCost) {
// lets not consume end for custom items that have disc procs.
// One might also want to filter out USE_ITEM_SPELL_SLOT, but DISCIPLINE_SPELL_SLOT are both #defined to the same thing ...
if (spells[spell_id].EndurCost && !isproc) {
auto end_cost = spells[spell_id].EndurCost;
if (mgb)
end_cost *= 2;
+13 -13
View File
@@ -94,7 +94,7 @@ void NPC::ResumeWandering()
{
if (GetGrid() < 0)
{ // we were paused by a quest
AIwalking_timer->Disable();
AI_walking_timer->Disable();
SetGrid( 0 - GetGrid());
if (cur_wp==-1)
{ // got here by a MoveTo()
@@ -103,10 +103,10 @@ void NPC::ResumeWandering()
}
Log.Out(Logs::Detail, Logs::Pathing, "Resume Wandering requested. Grid %d, wp %d", GetGrid(), cur_wp);
}
else if (AIwalking_timer->Enabled())
else if (AI_walking_timer->Enabled())
{ // we are at a waypoint paused normally
Log.Out(Logs::Detail, Logs::Pathing, "Resume Wandering on timed pause. Grid %d, wp %d", GetGrid(), cur_wp);
AIwalking_timer->Trigger(); // disable timer to end pause now
AI_walking_timer->Trigger(); // disable timer to end pause now
}
else
{
@@ -145,7 +145,7 @@ void NPC::PauseWandering(int pausetime)
}
else
{ // specified waiting time, he'll resume after that
AIwalking_timer->Start(pausetime*1000); // set the timer
AI_walking_timer->Start(pausetime*1000); // set the timer
}
} else {
Log.Out(Logs::General, Logs::Error, "NPC not on grid - can't pause wandering: %lu", (unsigned long)GetNPCTypeID());
@@ -162,7 +162,7 @@ void NPC::MoveTo(const glm::vec4& position, bool saveguardspot)
SetGrid( 0 - GetGrid()); // get him moving again
Log.Out(Logs::Detail, Logs::AI, "MoveTo during quest wandering. Canceling quest wandering and going back to grid %d when MoveTo is done.", GetGrid());
}
AIwalking_timer->Disable(); // disable timer in case he is paused at a wp
AI_walking_timer->Disable(); // disable timer in case he is paused at a wp
if (cur_wp>=0)
{ // we've not already done a MoveTo()
save_wp=cur_wp; // save the current waypoint
@@ -193,8 +193,8 @@ void NPC::MoveTo(const glm::vec4& position, bool saveguardspot)
m_CurrentWayPoint = position;
cur_wp_pause = 0;
pLastFightingDelayMoving = 0;
if(AIwalking_timer->Enabled())
AIwalking_timer->Start(100);
if(AI_walking_timer->Enabled())
AI_walking_timer->Start(100);
}
void NPC::UpdateWaypoint(int wp_index)
@@ -393,8 +393,8 @@ void NPC::SetWaypointPause()
//Declare time to wait on current WP
if (cur_wp_pause == 0) {
AIwalking_timer->Start(100);
AIwalking_timer->Trigger();
AI_walking_timer->Start(100);
AI_walking_timer->Trigger();
}
else
{
@@ -402,13 +402,13 @@ void NPC::SetWaypointPause()
switch (pausetype)
{
case 0: //Random Half
AIwalking_timer->Start((cur_wp_pause - zone->random.Int(0, cur_wp_pause-1)/2)*1000);
AI_walking_timer->Start((cur_wp_pause - zone->random.Int(0, cur_wp_pause-1)/2)*1000);
break;
case 1: //Full
AIwalking_timer->Start(cur_wp_pause*1000);
AI_walking_timer->Start(cur_wp_pause*1000);
break;
case 2: //Random Full
AIwalking_timer->Start(zone->random.Int(0, cur_wp_pause-1)*1000);
AI_walking_timer->Start(zone->random.Int(0, cur_wp_pause-1)*1000);
break;
}
}
@@ -484,7 +484,7 @@ bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, int speed, boo
Log.Out(Logs::Detail, Logs::AI, "Calc Position2 (%.3f, %.3f, %.3f): Jumping pure Z.", x, y, z);
return true;
}
Log.Out(Logs::Detail, Logs::AI, "Calc Position2 (%.3f, %.3f, %.3f) inWater=%d: We are there.", x, y, z, inWater);
// Log.Out(Logs::Detail, Logs::AI, "Calc Position2 (%.3f, %.3f, %.3f) inWater=%d: We are there.", x, y, z, inWater);
return false;
} else if ((std::abs(m_Position.x - x) < 0.1) && (std::abs(m_Position.y - y) < 0.1)) {
Log.Out(Logs::Detail, Logs::AI, "Calc Position2 (%.3f, %.3f, %.3f): X/Y difference <0.1, Jumping to target.", x, y, z);
+44 -27
View File
@@ -39,6 +39,7 @@
#include "client.h"
#include "corpse.h"
#include "entity.h"
#include "quest_parser_collection.h"
#include "guild_mgr.h"
#include "mob.h"
#include "net.h"
@@ -53,13 +54,16 @@
extern EntityList entity_list;
extern Zone* zone;
extern volatile bool ZoneLoaded;
extern volatile bool is_zone_loaded;
extern void CatchSignal(int);
extern WorldServer worldserver;
extern NetConnection net;
extern PetitionList petition_list;
extern uint32 numclients;
extern volatile bool RunLoops;
extern QuestParserCollection *parse;
// QuestParserCollection *parse = 0;
WorldServer::WorldServer()
: WorldConnection(EmuTCPConnection::packetModeZone)
@@ -85,7 +89,7 @@ WorldServer::~WorldServer() {
safe_delete(pack);
}*/
void WorldServer::SetZone(uint32 iZoneID, uint32 iInstanceID) {
void WorldServer::SetZoneData(uint32 iZoneID, uint32 iInstanceID) {
ServerPacket* pack = new ServerPacket(ServerOP_SetZone, sizeof(SetZone_Struct));
SetZone_Struct* szs = (SetZone_Struct*) pack->pBuffer;
szs->zoneid = iZoneID;
@@ -99,10 +103,9 @@ void WorldServer::SetZone(uint32 iZoneID, uint32 iInstanceID) {
void WorldServer::OnConnected() {
WorldConnection::OnConnected();
ServerPacket* pack;
//tell the launcher what name we were started with.
/* Tell the launcher what our information is */
pack = new ServerPacket(ServerOP_SetLaunchName,sizeof(LaunchName_Struct));
LaunchName_Struct* ln = (LaunchName_Struct*)pack->pBuffer;
strn0cpy(ln->launcher_name, m_launcherName.c_str(), 32);
@@ -110,28 +113,38 @@ void WorldServer::OnConnected() {
SendPacket(pack);
safe_delete(pack);
/* Tell the Worldserver basic information about this zone process */
pack = new ServerPacket(ServerOP_SetConnectInfo, sizeof(ServerConnectInfo));
ServerConnectInfo* sci = (ServerConnectInfo*) pack->pBuffer;
auto config = ZoneConfig::get();
sci->port = ZoneConfig::get()->ZonePort;
if(config->WorldAddress.length() > 0) {
strn0cpy(sci->address, config->WorldAddress.c_str(), 250);
}
if(config->LocalAddress.length() > 0) {
strn0cpy(sci->local_address, config->LocalAddress.c_str(), 250);
}
/* Fetch process ID */
if (getpid()){
sci->process_id = getpid();
}
else {
sci->process_id = 0;
}
SendPacket(pack);
safe_delete(pack);
if (ZoneLoaded) {
this->SetZone(zone->GetZoneID(), zone->GetInstanceID());
if (is_zone_loaded) {
this->SetZoneData(zone->GetZoneID(), zone->GetInstanceID());
entity_list.UpdateWho(true);
this->SendEmoteMessage(0, 0, 15, "Zone connect: %s", zone->GetLongName());
zone->GetTimeSync();
} else {
this->SetZone(0);
zone->GetTimeSync();
}
else {
this->SetZoneData(0);
}
pack = new ServerPacket(ServerOP_LSZoneBoot,sizeof(ZoneBoot_Struct));
@@ -174,7 +187,7 @@ void WorldServer::Process() {
break;
}
case ServerOP_ChannelMessage: {
if (!ZoneLoaded)
if (!is_zone_loaded)
break;
ServerChannelMessage_Struct* scm = (ServerChannelMessage_Struct*) pack->pBuffer;
if (scm->deliverto[0] == 0) {
@@ -207,7 +220,7 @@ void WorldServer::Process() {
}
case ServerOP_VoiceMacro: {
if (!ZoneLoaded)
if (!is_zone_loaded)
break;
ServerVoiceMacro_Struct* svm = (ServerVoiceMacro_Struct*) pack->pBuffer;
@@ -264,7 +277,7 @@ void WorldServer::Process() {
case ServerOP_SpawnCondition: {
if(pack->size != sizeof(ServerSpawnCondition_Struct))
break;
if (!ZoneLoaded)
if (!is_zone_loaded)
break;
ServerSpawnCondition_Struct* ssc = (ServerSpawnCondition_Struct*) pack->pBuffer;
@@ -274,7 +287,7 @@ void WorldServer::Process() {
case ServerOP_SpawnEvent: {
if(pack->size != sizeof(ServerSpawnEvent_Struct))
break;
if (!ZoneLoaded)
if (!is_zone_loaded)
break;
ServerSpawnEvent_Struct* sse = (ServerSpawnEvent_Struct*) pack->pBuffer;
@@ -285,7 +298,7 @@ void WorldServer::Process() {
case ServerOP_AcceptWorldEntrance: {
if(pack->size != sizeof(WorldToZone_Struct))
break;
if (!ZoneLoaded)
if (!is_zone_loaded)
break;
WorldToZone_Struct* wtz = (WorldToZone_Struct*) pack->pBuffer;
@@ -300,7 +313,7 @@ void WorldServer::Process() {
case ServerOP_ZoneToZoneRequest: {
if(pack->size != sizeof(ZoneToZone_Struct))
break;
if (!ZoneLoaded)
if (!is_zone_loaded)
break;
ZoneToZone_Struct* ztz = (ZoneToZone_Struct*) pack->pBuffer;
@@ -376,7 +389,7 @@ void WorldServer::Process() {
break;
}
case ServerOP_WhoAllReply:{
if(!ZoneLoaded)
if(!is_zone_loaded)
break;
@@ -403,7 +416,7 @@ void WorldServer::Process() {
break;
}
case ServerOP_EmoteMessage: {
if (!ZoneLoaded)
if (!is_zone_loaded)
break;
ServerEmoteMessage_Struct* sem = (ServerEmoteMessage_Struct*) pack->pBuffer;
if (sem->to[0] != 0) {
@@ -461,8 +474,8 @@ void WorldServer::Process() {
break;
}
// Annouce the change to the world
if (!ZoneLoaded) {
SetZone(0);
if (!is_zone_loaded) {
SetZoneData(0);
}
else {
SendEmoteMessage(0, 0, 15, "Zone shutdown: %s", zone->GetLongName());
@@ -479,8 +492,8 @@ void WorldServer::Process() {
break;
}
ServerZoneStateChange_struct* zst = (ServerZoneStateChange_struct *) pack->pBuffer;
if (ZoneLoaded) {
SetZone(zone->GetZoneID(), zone->GetInstanceID());
if (is_zone_loaded) {
SetZoneData(zone->GetZoneID(), zone->GetInstanceID());
if (zst->zoneid == zone->GetZoneID()) {
// This packet also doubles as "incoming client" notification, lets not shut down before they get here
zone->StartShutdownTimer(AUTHENTICATION_TIMEOUT * 1000);
@@ -503,8 +516,8 @@ void WorldServer::Process() {
break;
}
ServerZoneIncomingClient_Struct* szic = (ServerZoneIncomingClient_Struct*) pack->pBuffer;
if (ZoneLoaded) {
SetZone(zone->GetZoneID(), zone->GetInstanceID());
if (is_zone_loaded) {
SetZoneData(zone->GetZoneID(), zone->GetInstanceID());
if (szic->zoneid == zone->GetZoneID()) {
zone->AddAuth(szic);
// This packet also doubles as "incoming client" notification, lets not shut down before they get here
@@ -540,7 +553,7 @@ void WorldServer::Process() {
if (client != 0) {
if (skp->adminrank >= client->Admin()) {
client->WorldKick();
if (ZoneLoaded)
if (is_zone_loaded)
SendEmoteMessage(skp->adminname, 0, 0, "Remote Kick: %s booted in zone %s.", skp->name, zone->GetShortName());
else
SendEmoteMessage(skp->adminname, 0, 0, "Remote Kick: %s booted.", skp->name);
@@ -556,7 +569,7 @@ void WorldServer::Process() {
if (client != 0) {
if (skp->admin >= client->Admin()) {
client->GMKill();
if (ZoneLoaded)
if (is_zone_loaded)
SendEmoteMessage(skp->gmname, 0, 0, "Remote Kill: %s killed in zone %s.", skp->target, zone->GetShortName());
else
SendEmoteMessage(skp->gmname, 0, 0, "Remote Kill: %s killed.", skp->target);
@@ -594,7 +607,7 @@ void WorldServer::Process() {
std::cout << "Wrong size on ServerOP_GMGoto. Got: " << pack->size << ", Expected: " << sizeof(ServerGMGoto_Struct) << std::endl;
break;
}
if (!ZoneLoaded)
if (!is_zone_loaded)
break;
ServerGMGoto_Struct* gmg = (ServerGMGoto_Struct*) pack->pBuffer;
Client* client = entity_list.GetClientByName(gmg->gotoname);
@@ -1733,6 +1746,10 @@ void WorldServer::Process() {
database.LoadLogSettings(Log.log_settings);
break;
}
case ServerOP_ReloadPerlExportSettings: {
parse->LoadPerlEventExportSettings(parse->perl_event_export_settings);
break;
}
case ServerOP_CameraShake:
{
if(zone)
+1 -1
View File
@@ -37,7 +37,7 @@ public:
bool SendEmoteMessage(const char* to, uint32 to_guilddbid, uint32 type, const char* message, ...);
bool SendEmoteMessage(const char* to, uint32 to_guilddbid, int16 to_minstatus, uint32 type, const char* message, ...);
bool SendVoiceMacro(Client* From, uint32 Type, char* Target, uint32 MacroNumber, uint32 GroupOrRaidID = 0);
void SetZone(uint32 iZoneID, uint32 iInstanceID = 0);
void SetZoneData(uint32 iZoneID, uint32 iInstanceID = 0);
uint32 SendGroupIdRequest();
bool RezzPlayer(EQApplicationPacket* rpack, uint32 rezzexp, uint32 dbid, uint16 opcode);
bool IsOOCMuted() const { return(oocmuted); }
+33 -10
View File
@@ -74,7 +74,7 @@ extern Zone* zone;
Mutex MZoneShutdown;
volatile bool ZoneLoaded = false;
volatile bool is_zone_loaded = false;
Zone* zone = 0;
bool Zone::Bootup(uint32 iZoneID, uint32 iInstanceID, bool iStaticZone) {
@@ -82,9 +82,9 @@ bool Zone::Bootup(uint32 iZoneID, uint32 iInstanceID, bool iStaticZone) {
if (iZoneID == 0 || zonename == 0)
return false;
if (zone != 0 || ZoneLoaded) {
if (zone != 0 || is_zone_loaded) {
std::cerr << "Error: Zone::Bootup call when zone already booted!" << std::endl;
worldserver.SetZone(0);
worldserver.SetZoneData(0);
return false;
}
@@ -97,7 +97,7 @@ bool Zone::Bootup(uint32 iZoneID, uint32 iInstanceID, bool iStaticZone) {
if (!zone->Init(iStaticZone)) {
safe_delete(zone);
std::cerr << "Zone->Init failed" << std::endl;
worldserver.SetZone(0);
worldserver.SetZoneData(0);
return false;
}
zone->zonemap = Map::LoadMapFile(zone->map_name);
@@ -131,9 +131,9 @@ bool Zone::Bootup(uint32 iZoneID, uint32 iInstanceID, bool iStaticZone) {
}
}
ZoneLoaded = true;
is_zone_loaded = true;
worldserver.SetZone(iZoneID, iInstanceID);
worldserver.SetZoneData(iZoneID, iInstanceID);
if(iInstanceID != 0)
{
ServerPacket *pack = new ServerPacket(ServerOP_AdventureZoneData, sizeof(uint16));
@@ -660,12 +660,12 @@ void Zone::LoadMercSpells(){
}
bool Zone::IsLoaded() {
return ZoneLoaded;
return is_zone_loaded;
}
void Zone::Shutdown(bool quite)
{
if (!ZoneLoaded)
if (!is_zone_loaded)
return;
entity_list.StopMobAI();
@@ -699,7 +699,7 @@ void Zone::Shutdown(bool quite)
zone->SetZoneHasCurrentTime(false);
if (!quite)
Log.Out(Logs::General, Logs::Normal, "Zone shutdown: going to sleep");
ZoneLoaded = false;
is_zone_loaded = false;
zone->ResetAuth();
safe_delete(zone);
@@ -846,7 +846,7 @@ Zone::~Zone() {
safe_delete(watermap);
safe_delete(pathing);
if (worldserver.Connected()) {
worldserver.SetZone(0);
worldserver.SetZoneData(0);
}
safe_delete_array(short_name);
safe_delete_array(long_name);
@@ -1445,6 +1445,29 @@ void Zone::ClearNPCTypeCache(int id) {
}
}
void Zone::RepopClose(const glm::vec4& client_position, uint32 repop_distance)
{
if (!Depop())
return;
LinkedListIterator<Spawn2*> iterator(spawn2_list);
iterator.Reset();
while (iterator.MoreElements()) {
iterator.RemoveCurrent();
}
quest_manager.ClearAllTimers();
if (!database.PopulateZoneSpawnListClose(zoneid, spawn2_list, GetInstanceVersion(), client_position, repop_distance))
Log.Out(Logs::General, Logs::None, "Error in Zone::Repop: database.PopulateZoneSpawnList failed");
initgrids_timer.Start();
mod_repop();
}
void Zone::Repop(uint32 delay) {
if(!Depop())
+1
View File
@@ -140,6 +140,7 @@ public:
bool Depop(bool StartSpawnTimer = false);
void Repop(uint32 delay = 0);
void RepopClose(const glm::vec4& client_position, uint32 repop_distance);
void ClearNPCTypeCache(int id);
void SpawnStatus(Mob* client);
void ShowEnabledSpawnStatus(Mob* client);
+3 -3
View File
@@ -46,7 +46,7 @@ void ZoneDatabase::ZDBInitVars() {
ZoneDatabase::~ZoneDatabase() {
unsigned int x;
if (npc_spells_cache) {
for (x=0; x<=npc_spells_maxid; x++) {
for (x = 0; x <= npc_spells_maxid; x++) {
safe_delete_array(npc_spells_cache[x]);
}
safe_delete_array(npc_spells_cache);
@@ -54,7 +54,7 @@ ZoneDatabase::~ZoneDatabase() {
safe_delete_array(npc_spells_loadtried);
if (npc_spellseffects_cache) {
for (x=0; x<=npc_spellseffects_maxid; x++) {
for (x = 0; x <= npc_spellseffects_maxid; x++) {
safe_delete_array(npc_spellseffects_cache[x]);
}
safe_delete_array(npc_spellseffects_cache);
@@ -62,7 +62,7 @@ ZoneDatabase::~ZoneDatabase() {
safe_delete_array(npc_spellseffects_loadtried);
if (faction_array != nullptr) {
for (x=0; x <= max_faction; x++) {
for (x = 0; x <= max_faction; x++) {
if (faction_array[x] != 0)
safe_delete(faction_array[x]);
}
+2
View File
@@ -7,6 +7,7 @@
#include "../common/faction.h"
#include "../common/eqemu_logsys.h"
#include "aa_ability.h"
#include "event_codes.h"
class Client;
class Corpse;
@@ -358,6 +359,7 @@ public:
bool LoadSpawnGroups(const char* zone_name, uint16 version, SpawnGroupList* spawn_group_list);
bool LoadSpawnGroupsByID(int spawngroupid, SpawnGroupList* spawn_group_list);
bool PopulateZoneSpawnList(uint32 zoneid, LinkedList<Spawn2*> &spawn2_list, int16 version, uint32 repopdelay = 0);
bool PopulateZoneSpawnListClose(uint32 zoneid, LinkedList<Spawn2*> &spawn2_list, int16 version, const glm::vec4& client_position, uint32 repop_distance);
Spawn2* LoadSpawn2(LinkedList<Spawn2*> &spawn2_list, uint32 spawn2id, uint32 timeleft);
bool CreateSpawn2(Client *c, uint32 spawngroup, const char* zone, const glm::vec4& position, uint32 respawn, uint32 variance, uint16 condition, int16 cond_value);
void UpdateRespawnTime(uint32 id, uint16 instance_id,uint32 timeleft);