mirror of
https://github.com/EQEmu/Server.git
synced 2026-06-26 11:27:17 +00:00
Merge branch 'master' of https://github.com/EQEmu/Server into peq-expansions
This commit is contained in:
+6
-3
@@ -5,8 +5,9 @@ SET(zone_sources
|
||||
aa_ability.cpp
|
||||
aggro.cpp
|
||||
aggromanager.cpp
|
||||
aura.cpp
|
||||
api_service.cpp
|
||||
attack.cpp
|
||||
aura.cpp
|
||||
beacon.cpp
|
||||
bonuses.cpp
|
||||
bot.cpp
|
||||
@@ -140,12 +141,14 @@ SET(zone_sources
|
||||
zone.cpp
|
||||
zone_config.cpp
|
||||
zonedb.cpp
|
||||
zoning.cpp)
|
||||
zoning.cpp
|
||||
)
|
||||
|
||||
SET(zone_headers
|
||||
aa.h
|
||||
aa_ability.h
|
||||
aggromanager.h
|
||||
api_service.h
|
||||
aura.h
|
||||
basic_functions.h
|
||||
beacon.h
|
||||
@@ -158,7 +161,7 @@ SET(zone_headers
|
||||
command.h
|
||||
common.h
|
||||
corpse.h
|
||||
data_bucket.h
|
||||
data_bucket.h
|
||||
doors.h
|
||||
embparser.h
|
||||
embperl.h
|
||||
|
||||
+11
-2
@@ -251,9 +251,17 @@ bool Mob::CheckWillAggro(Mob *mob) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Mob *ownr = mob->GetOwner();
|
||||
if(ownr && ownr->IsClient() && !ownr->CastToClient()->ClientFinishedLoading())
|
||||
/**
|
||||
* Pets shouldn't scan for aggro
|
||||
*/
|
||||
if (this->GetOwner()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Mob *pet_owner = mob->GetOwner();
|
||||
if (pet_owner && pet_owner->IsClient()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
float iAggroRange = GetAggroRange();
|
||||
|
||||
@@ -727,6 +735,7 @@ type', in which case, the answer is yes.
|
||||
}
|
||||
|
||||
#ifdef BOTS
|
||||
// this is HIGHLY inefficient
|
||||
bool HasRuleDefined = false;
|
||||
bool IsBotAttackAllowed = false;
|
||||
IsBotAttackAllowed = Bot::IsBotAttackAllowed(mob1, mob2, HasRuleDefined);
|
||||
|
||||
@@ -0,0 +1,901 @@
|
||||
/**
|
||||
* EQEmulator: Everquest Server Emulator
|
||||
* Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
* are required to give you total support for your newly bought product;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include <memory>
|
||||
#include "../common/net/websocket_server.h"
|
||||
#include "../common/eqemu_logsys.h"
|
||||
#include "zonedb.h"
|
||||
#include "client.h"
|
||||
#include "entity.h"
|
||||
#include "corpse.h"
|
||||
#include "api_service.h"
|
||||
#include "npc.h"
|
||||
#include "object.h"
|
||||
#include "zone.h"
|
||||
#include "doors.h"
|
||||
#include <iostream>
|
||||
|
||||
extern Zone *zone;
|
||||
|
||||
EQ::Net::WebsocketLoginStatus
|
||||
CheckLogin(EQ::Net::WebsocketServerConnection *connection, const std::string &username, const std::string &password)
|
||||
{
|
||||
EQ::Net::WebsocketLoginStatus ret;
|
||||
ret.logged_in = false;
|
||||
|
||||
ret.account_id = database.CheckLogin(username.c_str(), password.c_str());
|
||||
|
||||
if (ret.account_id == 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
char account_name[64];
|
||||
database.GetAccountName(static_cast<uint32>(ret.account_id), account_name);
|
||||
ret.account_name = account_name;
|
||||
ret.logged_in = true;
|
||||
ret.status = database.CheckStatus(ret.account_id);
|
||||
return ret;
|
||||
}
|
||||
|
||||
Json::Value ApiGetPacketStatistics(EQ::Net::WebsocketServerConnection *connection, Json::Value params)
|
||||
{
|
||||
if (zone->GetZoneID() == 0) {
|
||||
throw EQ::Net::WebsocketException("Zone must be loaded to invoke this call");
|
||||
}
|
||||
|
||||
Json::Value response;
|
||||
auto &list = entity_list.GetClientList();
|
||||
|
||||
for (auto &iter : list) {
|
||||
auto client = iter.second;
|
||||
auto connection = client->Connection();
|
||||
auto opts = connection->GetManager()->GetOptions();
|
||||
auto eqs_stats = connection->GetStats();
|
||||
auto &stats = eqs_stats.DaybreakStats;
|
||||
auto now = EQ::Net::Clock::now();
|
||||
auto sec_since_stats_reset = std::chrono::duration_cast<std::chrono::duration<double>>(
|
||||
now - stats.created
|
||||
).count();
|
||||
|
||||
Json::Value row;
|
||||
|
||||
row["client_id"] = client->GetID();
|
||||
row["client_name"] = client->GetCleanName();
|
||||
row["seconds_since_reset"] = sec_since_stats_reset;
|
||||
row["sent_bytes"] = stats.sent_bytes;
|
||||
row["receive_bytes"] = stats.recv_bytes;
|
||||
row["min_ping"] = stats.min_ping;
|
||||
row["max_ping"] = stats.max_ping;
|
||||
row["last_ping"] = stats.last_ping;
|
||||
row["average_ping"] = stats.avg_ping;
|
||||
row["realtime_receive_packets"] = stats.recv_packets;
|
||||
row["realtime_sent_packets"] = stats.sent_packets;
|
||||
row["sync_recv_packets"] = stats.sync_recv_packets;
|
||||
row["sync_sent_packets"] = stats.sync_sent_packets;
|
||||
row["sync_remote_recv_packets"] = stats.sync_remote_recv_packets;
|
||||
row["sync_remote_sent_packets"] = stats.sync_remote_sent_packets;
|
||||
row["packet_loss_in"] = (100.0 * (1.0 - static_cast<double>(stats.sync_recv_packets) /
|
||||
static_cast<double>(stats.sync_remote_sent_packets)));
|
||||
row["packet_loss_out"] = (100.0 * (1.0 - static_cast<double>(stats.sync_remote_recv_packets) /
|
||||
static_cast<double>(stats.sync_sent_packets)));
|
||||
row["resent_packets"] = stats.resent_packets;
|
||||
row["resent_fragments"] = stats.resent_fragments;
|
||||
row["resent_non_fragments"] = stats.resent_full;
|
||||
row["dropped_datarate_packets"] = stats.dropped_datarate_packets;
|
||||
|
||||
Json::Value sent_packet_types;
|
||||
|
||||
for (auto i = 0; i < _maxEmuOpcode; ++i) {
|
||||
auto count = eqs_stats.SentCount[i];
|
||||
if (count > 0) {
|
||||
sent_packet_types[OpcodeNames[i]] = count;
|
||||
}
|
||||
}
|
||||
|
||||
Json::Value receive_packet_types;
|
||||
|
||||
for (auto i = 0; i < _maxEmuOpcode; ++i) {
|
||||
auto count = eqs_stats.RecvCount[i];
|
||||
if (count > 0) {
|
||||
receive_packet_types[OpcodeNames[i]] = count;
|
||||
}
|
||||
}
|
||||
|
||||
row["sent_packet_types"] = sent_packet_types;
|
||||
row["receive_packet_types"] = receive_packet_types;
|
||||
|
||||
response.append(row);
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
Json::Value ApiGetOpcodeList(EQ::Net::WebsocketServerConnection *connection, Json::Value params)
|
||||
{
|
||||
if (zone->GetZoneID() == 0) {
|
||||
throw EQ::Net::WebsocketException("Zone must be loaded to invoke this call");
|
||||
}
|
||||
|
||||
Json::Value response;
|
||||
for (auto i = 0; i < _maxEmuOpcode; ++i) {
|
||||
Json::Value row = OpcodeNames[i];
|
||||
|
||||
response.append(row);
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
Json::Value ApiGetNpcListDetail(EQ::Net::WebsocketServerConnection *connection, Json::Value params)
|
||||
{
|
||||
if (zone->GetZoneID() == 0) {
|
||||
throw EQ::Net::WebsocketException("Zone must be loaded to invoke this call");
|
||||
}
|
||||
|
||||
Json::Value response;
|
||||
auto &list = entity_list.GetNPCList();
|
||||
|
||||
for (auto &iter : list) {
|
||||
auto npc = iter.second;
|
||||
Json::Value row;
|
||||
|
||||
/**
|
||||
* Main
|
||||
*/
|
||||
row["id"] = npc->GetID();
|
||||
row["clean_name"] = npc->GetCleanName();
|
||||
row["x"] = npc->GetX();
|
||||
row["y"] = npc->GetY();
|
||||
row["z"] = npc->GetZ();
|
||||
row["heading"] = npc->GetHeading();
|
||||
|
||||
/**
|
||||
* Rest
|
||||
*/
|
||||
row["accuracy_rating"] = npc->GetAccuracyRating();
|
||||
row["ai_has_spells"] = npc->AI_HasSpells();
|
||||
row["ai_has_spells_effects"] = npc->AI_HasSpellsEffects();
|
||||
row["ammo_id_file"] = npc->GetAmmoIDfile();
|
||||
row["attack_delay"] = npc->GetAttackDelay();
|
||||
row["attack_speed"] = npc->GetAttackSpeed();
|
||||
row["avoidance_rating"] = npc->GetAvoidanceRating();
|
||||
row["base_damage"] = npc->GetBaseDamage();
|
||||
row["combat_event"] = npc->GetCombatEvent();
|
||||
row["copper"] = npc->GetCopper();
|
||||
row["count_loot"] = npc->CountLoot();
|
||||
row["drops_global_loot"] = npc->DropsGlobalLoot();
|
||||
row["gold"] = npc->GetGold();
|
||||
row["grid"] = npc->GetGrid();
|
||||
row["has_private_corpse"] = npc->HasPrivateCorpse();
|
||||
row["is_animal"] = npc->IsAnimal();
|
||||
row["is_guarding"] = npc->IsGuarding();
|
||||
row["is_ldon_locked"] = npc->IsLDoNLocked();
|
||||
row["is_ldon_trap_detected"] = npc->IsLDoNTrapDetected();
|
||||
row["is_ldon_trapped"] = npc->IsLDoNTrapped();
|
||||
row["is_merchant_open"] = npc->IsMerchantOpen();
|
||||
row["is_not_targetable_with_hotkey"] = npc->IsNotTargetableWithHotkey();
|
||||
row["is_proximity_set"] = npc->IsProximitySet();
|
||||
row["is_taunting"] = npc->IsTaunting();
|
||||
row["ldon_locked_skill"] = npc->GetLDoNLockedSkill();
|
||||
row["ldon_trap_spell_id"] = npc->GetLDoNTrapSpellID();
|
||||
row["ldon_trap_type"] = npc->GetLDoNTrapType();
|
||||
row["loottable_id"] = npc->GetLoottableID();
|
||||
row["max_dmg"] = npc->GetMaxDMG();
|
||||
row["max_wp"] = npc->GetMaxWp();
|
||||
row["min_damage"] = npc->GetMinDamage();
|
||||
row["min_dmg"] = npc->GetMinDMG();
|
||||
row["npc_spells_effects_id"] = npc->GetNPCSpellsEffectsID();
|
||||
row["npc_spells_id"] = npc->GetNPCSpellsID();
|
||||
row["npchp_regen"] = npc->GetNPCHPRegen();
|
||||
row["num_merc_types"] = npc->GetNumMercTypes();
|
||||
row["num_mercs"] = npc->GetNumMercs();
|
||||
row["number_of_attacks"] = npc->GetNumberOfAttacks();
|
||||
row["pet_spell_id"] = npc->GetPetSpellID();
|
||||
row["platinum"] = npc->GetPlatinum();
|
||||
row["prim_skill"] = npc->GetPrimSkill();
|
||||
|
||||
if (npc->IsProximitySet()) {
|
||||
row["proximity_max_x"] = npc->GetProximityMaxX();
|
||||
row["proximity_max_y"] = npc->GetProximityMaxY();
|
||||
row["proximity_max_z"] = npc->GetProximityMaxZ();
|
||||
row["proximity_min_x"] = npc->GetProximityMinX();
|
||||
row["proximity_min_y"] = npc->GetProximityMinY();
|
||||
row["proximity_min_z"] = npc->GetProximityMinZ();
|
||||
}
|
||||
|
||||
row["ranged_skill"] = npc->GetRangedSkill();
|
||||
row["raw_ac"] = npc->GetRawAC();
|
||||
row["sec_skill"] = npc->GetSecSkill();
|
||||
row["silver"] = npc->GetSilver();
|
||||
row["slow_mitigation"] = npc->GetSlowMitigation();
|
||||
row["sp2"] = npc->GetSp2();
|
||||
row["swarm_owner"] = npc->GetSwarmOwner();
|
||||
row["swarm_target"] = npc->GetSwarmTarget();
|
||||
row["waypoint_max"] = npc->GetWaypointMax();
|
||||
row["will_aggro_npcs"] = npc->WillAggroNPCs();
|
||||
|
||||
response.append(row);
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
Json::Value ApiGetDoorListDetail(EQ::Net::WebsocketServerConnection *connection, Json::Value params)
|
||||
{
|
||||
if (zone->GetZoneID() == 0) {
|
||||
throw EQ::Net::WebsocketException("Zone must be loaded to invoke this call");
|
||||
}
|
||||
|
||||
Json::Value response;
|
||||
auto &door_list = entity_list.GetDoorsList();
|
||||
|
||||
for (auto itr : door_list) {
|
||||
Doors *door = itr.second;
|
||||
|
||||
Json::Value row;
|
||||
|
||||
row["door_name"] = door->GetDoorName();
|
||||
row["client_version_mask"] = door->GetClientVersionMask();
|
||||
row["disable_timer"] = door->GetDisableTimer();
|
||||
row["door_db_id"] = door->GetDoorDBID();
|
||||
row["door_id"] = door->GetDoorID();
|
||||
row["door_param"] = door->GetDoorParam();
|
||||
row["entity_id"] = door->GetEntityID();
|
||||
row["guild_id"] = door->GetGuildID();
|
||||
row["incline"] = door->GetIncline();
|
||||
row["invert_state"] = door->GetInvertState();
|
||||
row["is_door"] = door->IsDoor();
|
||||
row["is_door_open"] = door->IsDoorOpen();
|
||||
row["is_ldon_door"] = door->IsLDoNDoor();
|
||||
row["key_item"] = door->GetKeyItem();
|
||||
row["lockpick"] = door->GetLockpick();
|
||||
row["no_keyring"] = door->GetNoKeyring();
|
||||
row["open_type"] = door->GetOpenType();
|
||||
row["size"] = door->GetSize();
|
||||
row["trigger_door_id"] = door->GetTriggerDoorID();
|
||||
row["trigger_type"] = door->GetTriggerType();
|
||||
row["x"] = door->GetX();
|
||||
row["y"] = door->GetY();
|
||||
row["z"] = door->GetZ();
|
||||
|
||||
response.append(row);
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
Json::Value ApiGetCorpseListDetail(EQ::Net::WebsocketServerConnection *connection, Json::Value params)
|
||||
{
|
||||
if (zone->GetZoneID() == 0) {
|
||||
throw EQ::Net::WebsocketException("Zone must be loaded to invoke this call");
|
||||
}
|
||||
|
||||
Json::Value response;
|
||||
auto &corpse_list = entity_list.GetCorpseList();
|
||||
|
||||
for (auto itr : corpse_list) {
|
||||
auto corpse = itr.second;
|
||||
|
||||
Json::Value row;
|
||||
|
||||
row["char_id"] = corpse->GetCharID();
|
||||
row["copper"] = corpse->GetCopper();
|
||||
row["corpse_dbid"] = corpse->GetCorpseDBID();
|
||||
row["count_items"] = corpse->CountItems();
|
||||
row["decay_time"] = corpse->GetDecayTime();
|
||||
row["gold"] = corpse->GetGold();
|
||||
row["is_become_npc_corpse"] = corpse->IsBecomeNPCCorpse();
|
||||
row["is_being_looted"] = corpse->IsBeingLooted();
|
||||
row["is_corpse"] = corpse->IsCorpse();
|
||||
row["is_locked"] = corpse->IsLocked();
|
||||
row["is_npc_corpse"] = corpse->IsNPCCorpse();
|
||||
row["is_player_corpse"] = corpse->IsPlayerCorpse();
|
||||
row["is_rezzed"] = corpse->IsRezzed();
|
||||
row["owner_name"] = corpse->GetOwnerName();
|
||||
row["platinum"] = corpse->GetPlatinum();
|
||||
row["player_kill_item"] = corpse->GetPlayerKillItem();
|
||||
row["rez_exp"] = corpse->GetRezExp();
|
||||
row["rez_time"] = corpse->GetRezTime();
|
||||
row["silver"] = corpse->GetSilver();
|
||||
|
||||
response.append(row);
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
Json::Value ApiGetObjectListDetail(EQ::Net::WebsocketServerConnection *connection, Json::Value params)
|
||||
{
|
||||
if (zone->GetZoneID() == 0) {
|
||||
throw EQ::Net::WebsocketException("Zone must be loaded to invoke this call");
|
||||
}
|
||||
|
||||
Json::Value response;
|
||||
auto &list = entity_list.GetObjectList();
|
||||
|
||||
for (auto &iter : list) {
|
||||
auto object = iter.second;
|
||||
|
||||
Json::Value row;
|
||||
|
||||
row["display_name"] = object->GetDisplayName();
|
||||
row["dbid"] = object->GetDBID();
|
||||
row["heading_data"] = object->GetHeadingData();
|
||||
row["icon"] = object->GetIcon();
|
||||
row["is_ground_spawn"] = object->IsGroundSpawn();
|
||||
row["item_id"] = object->GetItemID();
|
||||
row["model_name"] = object->GetModelName();
|
||||
row["size"] = object->GetSize();
|
||||
row["solid_type"] = object->GetSolidType();
|
||||
row["tilt_x"] = object->GetTiltX();
|
||||
row["tilt_y"] = object->GetTiltY();
|
||||
row["type"] = object->GetType();
|
||||
row["x"] = object->GetX();
|
||||
row["y"] = object->GetY();
|
||||
row["z"] = object->GetZ();
|
||||
|
||||
response.append(row);
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
Json::Value ApiGetMobListDetail(EQ::Net::WebsocketServerConnection *connection, Json::Value params)
|
||||
{
|
||||
if (zone->GetZoneID() == 0) {
|
||||
throw EQ::Net::WebsocketException("Zone must be loaded to invoke this call");
|
||||
}
|
||||
|
||||
Json::Value response;
|
||||
auto &list = entity_list.GetMobList();
|
||||
|
||||
for (auto &iter : list) {
|
||||
auto mob = iter.second;
|
||||
|
||||
Json::Value row;
|
||||
|
||||
/**
|
||||
* Main
|
||||
*/
|
||||
row["id"] = mob->GetID();
|
||||
row["clean_name"] = mob->GetCleanName();
|
||||
row["x"] = mob->GetX();
|
||||
row["y"] = mob->GetY();
|
||||
row["z"] = mob->GetZ();
|
||||
row["heading"] = mob->GetHeading();
|
||||
|
||||
/**
|
||||
* Rest
|
||||
*/
|
||||
row["ac"] = mob->GetAC();
|
||||
row["ac_softcap"] = mob->GetACSoftcap();
|
||||
row["ac_sum"] = mob->ACSum();
|
||||
row["active_light_type"] = mob->GetActiveLightType();
|
||||
row["aggro_range"] = mob->GetAggroRange();
|
||||
row["allow_beneficial"] = mob->GetAllowBeneficial();
|
||||
row["animation"] = mob->GetAnimation();
|
||||
row["assist_range"] = mob->GetAssistRange();
|
||||
row["aura_slots"] = mob->GetAuraSlots();
|
||||
row["base_fear_speed"] = mob->GetBaseFearSpeed();
|
||||
row["base_runspeed"] = mob->GetBaseRunspeed();
|
||||
row["base_size"] = mob->GetBaseSize();
|
||||
row["base_walkspeed"] = mob->GetBaseWalkspeed();
|
||||
row["beard"] = mob->GetBeard();
|
||||
row["beard_color"] = mob->GetBeardColor();
|
||||
row["best_melee_skill"] = mob->GetBestMeleeSkill();
|
||||
row["calc_fear_resist_chance"] = mob->CalcFearResistChance();
|
||||
row["calc_resist_chance_bonus"] = mob->CalcResistChanceBonus();
|
||||
row["can_block_spell"] = mob->CanBlockSpell();
|
||||
row["can_facestab"] = mob->CanFacestab();
|
||||
row["casted_spell_inv_slot"] = mob->GetCastedSpellInvSlot();
|
||||
row["casting_spell_id"] = mob->CastingSpellID();
|
||||
row["charmed"] = mob->Charmed();
|
||||
row["check_last_los_state"] = mob->CheckLastLosState();
|
||||
row["class"] = mob->GetClass();
|
||||
row["class_level_factor"] = mob->GetClassLevelFactor();
|
||||
row["class_race_ac_bonus"] = mob->GetClassRaceACBonus();
|
||||
row["compute_defense"] = mob->compute_defense();
|
||||
row["count_dispellable_buffs"] = mob->CountDispellableBuffs();
|
||||
row["cripp_blow_chance"] = mob->GetCrippBlowChance();
|
||||
row["cur_wp"] = mob->GetCurWp();
|
||||
row["cwp"] = mob->GetCWP();
|
||||
row["cwpp"] = mob->GetCWPP();
|
||||
row["divine_aura"] = mob->DivineAura();
|
||||
row["do_casting_checks"] = mob->DoCastingChecks();
|
||||
row["dont_buff_me_before"] = mob->DontBuffMeBefore();
|
||||
row["dont_cure_me_before"] = mob->DontCureMeBefore();
|
||||
row["dont_dot_me_before"] = mob->DontDotMeBefore();
|
||||
row["dont_heal_me_before"] = mob->DontHealMeBefore();
|
||||
row["dont_root_me_before"] = mob->DontRootMeBefore();
|
||||
row["dont_snare_me_before"] = mob->DontSnareMeBefore();
|
||||
row["drakkin_details"] = mob->GetDrakkinDetails();
|
||||
row["drakkin_heritage"] = mob->GetDrakkinHeritage();
|
||||
row["drakkin_tattoo"] = mob->GetDrakkinTattoo();
|
||||
row["emote_id"] = mob->GetEmoteID();
|
||||
row["equipment_light_type"] = mob->GetEquipmentLightType();
|
||||
row["eye_color1"] = mob->GetEyeColor1();
|
||||
row["eye_color2"] = mob->GetEyeColor2();
|
||||
row["fear_speed"] = mob->GetFearSpeed();
|
||||
row["flurry_chance"] = mob->GetFlurryChance();
|
||||
row["follow_can_run"] = mob->GetFollowCanRun();
|
||||
row["follow_distance"] = mob->GetFollowDistance();
|
||||
row["follow_id"] = mob->GetFollowID();
|
||||
row["gender"] = mob->GetGender();
|
||||
row["hair_color"] = mob->GetHairColor();
|
||||
row["hair_style"] = mob->GetHairStyle();
|
||||
row["has_active_song"] = mob->HasActiveSong();
|
||||
row["has_assist_aggro"] = mob->HasAssistAggro();
|
||||
row["has_died"] = mob->HasDied();
|
||||
row["has_disc_buff"] = mob->HasDiscBuff();
|
||||
row["has_endur_upkeep"] = mob->HasEndurUpkeep();
|
||||
row["has_free_aura_slots"] = mob->HasFreeAuraSlots();
|
||||
row["has_free_trap_slots"] = mob->HasFreeTrapSlots();
|
||||
row["has_mgb"] = mob->HasMGB();
|
||||
row["has_numhits"] = mob->HasNumhits();
|
||||
row["has_pet"] = mob->HasPet();
|
||||
row["has_pet_affinity"] = mob->HasPetAffinity();
|
||||
row["has_primary_aggro"] = mob->HasPrimaryAggro();
|
||||
row["has_project_illusion"] = mob->HasProjectIllusion();
|
||||
row["has_projectile_attack"] = mob->HasProjectileAttack();
|
||||
row["has_shield_equiped"] = mob->HasShieldEquiped();
|
||||
row["has_special_abilities"] = mob->HasSpecialAbilities();
|
||||
row["has_tar_reflection"] = mob->HasTargetReflection();
|
||||
row["has_temp_pets_active"] = mob->HasTempPetsActive();
|
||||
row["has_two_hand_blunt_equiped"] = mob->HasTwoHandBluntEquiped();
|
||||
row["has_two_hander_equipped"] = mob->HasTwoHanderEquipped();
|
||||
row["has_virus"] = mob->HasVirus();
|
||||
row["hate_summon"] = mob->HateSummon();
|
||||
row["helm_texture"] = mob->GetHelmTexture();
|
||||
row["hp"] = mob->GetHP();
|
||||
row["improved_taunt"] = mob->ImprovedTaunt();
|
||||
row["innate_light_type"] = mob->GetInnateLightType();
|
||||
row["is_ai_controlled"] = mob->IsAIControlled();
|
||||
row["is_amnesiad"] = mob->IsAmnesiad();
|
||||
row["is_animation"] = mob->IsAnimation();
|
||||
row["is_blind"] = mob->IsBlind();
|
||||
row["is_casting"] = mob->IsCasting();
|
||||
row["is_charmed"] = mob->IsCharmed();
|
||||
row["is_destructible_object"] = mob->IsDestructibleObject();
|
||||
row["is_engaged"] = mob->IsEngaged();
|
||||
row["is_enraged"] = mob->IsEnraged();
|
||||
row["is_familiar"] = mob->IsFamiliar();
|
||||
row["is_feared"] = mob->IsFeared();
|
||||
row["is_findable"] = mob->IsFindable();
|
||||
row["is_focused"] = mob->IsFocused();
|
||||
row["is_g_held"] = mob->IsGHeld();
|
||||
row["is_grouped"] = mob->IsGrouped();
|
||||
row["is_held"] = mob->IsHeld();
|
||||
row["is_looting"] = mob->IsLooting();
|
||||
row["is_melee_disabled"] = mob->IsMeleeDisabled();
|
||||
row["is_mezzed"] = mob->IsMezzed();
|
||||
row["is_moved"] = mob->IsMoved();
|
||||
row["is_moving"] = mob->IsMoving();
|
||||
row["is_no_cast"] = mob->IsNoCast();
|
||||
row["is_off_hand_atk"] = mob->IsOffHandAtk();
|
||||
row["is_pet_owner_client"] = mob->IsPetOwnerClient();
|
||||
row["is_pet_regroup"] = mob->IsPetRegroup();
|
||||
row["is_pet_stop"] = mob->IsPetStop();
|
||||
row["is_pseudo_rooted"] = mob->IsPseudoRooted();
|
||||
row["is_raid_grouped"] = mob->IsRaidGrouped();
|
||||
row["is_rare_spawn"] = mob->IsRareSpawn();
|
||||
row["is_roamer"] = mob->IsRoamer();
|
||||
row["is_rooted"] = mob->IsRooted();
|
||||
row["is_running"] = mob->IsRunning();
|
||||
row["is_silenced"] = mob->IsSilenced();
|
||||
row["is_stunned"] = mob->IsStunned();
|
||||
row["is_tar_lock_pet"] = mob->IsTargetLockPet();
|
||||
row["is_tarable"] = mob->IsTargetable();
|
||||
row["is_tared"] = mob->IsTargeted();
|
||||
row["is_temp_pet"] = mob->IsTempPet();
|
||||
row["is_trackable"] = mob->IsTrackable();
|
||||
row["item_hp_bonuses"] = mob->GetItemHPBonuses();
|
||||
row["last_name"] = mob->GetLastName();
|
||||
row["level"] = mob->GetLevel();
|
||||
row["luclin_face"] = mob->GetLuclinFace();
|
||||
row["mana"] = mob->GetMana();
|
||||
row["mana_percent"] = mob->GetManaPercent();
|
||||
row["mana_ratio"] = mob->GetManaRatio();
|
||||
row["max_hp"] = mob->GetMaxHP();
|
||||
row["max_mana"] = mob->GetMaxMana();
|
||||
row["melee_mitigation"] = mob->GetMeleeMitigation();
|
||||
row["mitigation_ac"] = mob->GetMitigationAC();
|
||||
row["movespeed"] = mob->GetMovespeed();
|
||||
row["name"] = mob->GetName();
|
||||
row["next_hp_event"] = mob->GetNextHPEvent();
|
||||
row["next_inc_hp_event"] = mob->GetNextIncHPEvent();
|
||||
row["npc_assist_cap"] = mob->NPCAssistCap();
|
||||
row["npc_type_id"] = mob->GetNPCTypeID();
|
||||
row["orig_level"] = mob->GetOrigLevel();
|
||||
row["orig_name"] = mob->GetOrigName();
|
||||
row["owner_id"] = mob->GetOwnerID();
|
||||
row["pet_id"] = mob->GetPetID();
|
||||
row["pet_power"] = mob->GetPetPower();
|
||||
row["pet_tar_lock_id"] = mob->GetPetTargetLockID();
|
||||
row["qglobal"] = mob->GetQglobal();
|
||||
row["race"] = mob->GetRace();
|
||||
row["run_anim_speed"] = mob->GetRunAnimSpeed();
|
||||
row["sanctuary"] = mob->Sanctuary();
|
||||
row["see_hide"] = mob->SeeHide();
|
||||
row["see_improved_hide"] = mob->SeeImprovedHide();
|
||||
row["see_invisible"] = mob->SeeInvisible();
|
||||
row["see_invisible_undead"] = mob->SeeInvisibleUndead();
|
||||
row["size"] = mob->GetSize();
|
||||
row["slow_mitigation"] = mob->GetSlowMitigation();
|
||||
row["snared_amount"] = mob->GetSnaredAmount();
|
||||
row["spawned"] = mob->Spawned();
|
||||
row["spell_hp_bonuses"] = mob->GetSpellHPBonuses();
|
||||
row["spell_light_type"] = mob->GetSpellLightType();
|
||||
row["spell_power_distance_mod"] = mob->GetSpellPowerDistanceMod();
|
||||
row["spell_x"] = mob->GetSpellX();
|
||||
row["spell_y"] = mob->GetSpellY();
|
||||
row["spell_z"] = mob->GetSpellZ();
|
||||
row["tar_ring_x"] = mob->GetTargetRingX();
|
||||
row["tar_ring_y"] = mob->GetTargetRingY();
|
||||
row["tar_ring_z"] = mob->GetTargetRingZ();
|
||||
row["temp_pet_count"] = mob->GetTempPetCount();
|
||||
row["texture"] = mob->GetTexture();
|
||||
row["trap_slots"] = mob->GetTrapSlots();
|
||||
row["try_death_save"] = mob->TryDeathSave();
|
||||
row["try_divine_save"] = mob->TryDivineSave();
|
||||
row["try_spell_on_death"] = mob->TrySpellOnDeath();
|
||||
row["update_active_light"] = mob->UpdateActiveLight();
|
||||
row["wander_type"] = mob->GetWanderType();
|
||||
|
||||
response.append(row);
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
Json::Value ApiGetClientListDetail(EQ::Net::WebsocketServerConnection *connection, Json::Value params)
|
||||
{
|
||||
if (zone->GetZoneID() == 0) {
|
||||
throw EQ::Net::WebsocketException("Zone must be loaded to invoke this call");
|
||||
}
|
||||
|
||||
Json::Value response;
|
||||
auto &list = entity_list.GetClientList();
|
||||
|
||||
for (auto &iter : list) {
|
||||
auto client = iter.second;
|
||||
|
||||
Json::Value row;
|
||||
|
||||
/**
|
||||
* Main
|
||||
*/
|
||||
row["id"] = client->GetID();
|
||||
row["clean_name"] = client->GetCleanName();
|
||||
row["x"] = client->GetX();
|
||||
row["y"] = client->GetY();
|
||||
row["z"] = client->GetZ();
|
||||
row["heading"] = client->GetHeading();
|
||||
|
||||
/**
|
||||
* Rest
|
||||
*/
|
||||
row["aa_percent"] = client->GetAAPercent();
|
||||
row["aa_points"] = client->GetAAPoints();
|
||||
row["aaxp"] = client->GetAAXP();
|
||||
row["account_age"] = client->GetAccountAge();
|
||||
row["account_creation"] = client->GetAccountCreation();
|
||||
row["account_id"] = client->AccountID();
|
||||
row["account_name"] = client->AccountName();
|
||||
row["act_agi"] = client->GetActAGI();
|
||||
row["act_cha"] = client->GetActCHA();
|
||||
row["act_dex"] = client->GetActDEX();
|
||||
row["act_int"] = client->GetActINT();
|
||||
row["act_sta"] = client->GetActSTA();
|
||||
row["act_str"] = client->GetActSTR();
|
||||
row["act_wis"] = client->GetActWIS();
|
||||
row["active_task_count"] = client->GetActiveTaskCount();
|
||||
row["admin"] = client->Admin();
|
||||
row["aggro_count"] = client->GetAggroCount();
|
||||
row["aggro_meter_available"] = client->AggroMeterAvailable();
|
||||
row["all_money"] = client->GetAllMoney();
|
||||
row["anon"] = client->GetAnon();
|
||||
row["atk_rating"] = client->GetATKRating();
|
||||
row["auto_attack_enabled"] = client->AutoAttackEnabled();
|
||||
row["auto_fire_enabled"] = client->AutoFireEnabled();
|
||||
row["auto_split_enabled"] = client->AutoSplitEnabled();
|
||||
row["base_agi"] = client->GetBaseAGI();
|
||||
row["base_beard"] = client->GetBaseBeard();
|
||||
row["base_beard_color"] = client->GetBaseBeardColor();
|
||||
row["base_cha"] = client->GetBaseCHA();
|
||||
row["base_class"] = client->GetBaseClass();
|
||||
row["base_corrup"] = client->GetBaseCorrup();
|
||||
row["base_details"] = client->GetBaseDetails();
|
||||
row["base_dex"] = client->GetBaseDEX();
|
||||
row["base_eye_color"] = client->GetBaseEyeColor();
|
||||
row["base_face"] = client->GetBaseFace();
|
||||
row["base_gender"] = client->GetBaseGender();
|
||||
row["base_hair_color"] = client->GetBaseHairColor();
|
||||
row["base_hair_style"] = client->GetBaseHairStyle();
|
||||
row["base_heritage"] = client->GetBaseHeritage();
|
||||
row["base_hp"] = client->GetBaseHP();
|
||||
row["base_int"] = client->GetBaseINT();
|
||||
row["base_ph_r"] = client->GetBasePhR();
|
||||
row["base_race"] = client->GetBaseRace();
|
||||
row["base_sta"] = client->GetBaseSTA();
|
||||
row["base_str"] = client->GetBaseSTR();
|
||||
row["base_tattoo"] = client->GetBaseTattoo();
|
||||
row["base_wis"] = client->GetBaseWIS();
|
||||
row["become_npc_level"] = client->GetBecomeNPCLevel();
|
||||
row["boat_id"] = client->GetBoatID();
|
||||
row["buyer_welcome_message"] = client->GetBuyerWelcomeMessage();
|
||||
row["calc_atk"] = client->CalcATK();
|
||||
row["calc_base_mana"] = client->CalcBaseMana();
|
||||
row["calc_current_weight"] = client->CalcCurrentWeight();
|
||||
row["calc_endurance_regen_cap"] = client->CalcEnduranceRegenCap();
|
||||
row["calc_hp_regen_cap"] = client->CalcHPRegenCap();
|
||||
row["calc_mana_regen_cap"] = client->CalcManaRegenCap();
|
||||
row["calc_max_mana"] = client->CalcMaxMana();
|
||||
row["can_fast_regen"] = client->CanFastRegen();
|
||||
row["can_fish"] = client->CanFish();
|
||||
row["can_med_on_horse"] = client->CanMedOnHorse();
|
||||
row["carried_money"] = client->GetCarriedMoney();
|
||||
row["char_max_level_from_bucket"] = client->GetCharMaxLevelFromBucket();
|
||||
row["char_max_level_from_q_global"] = client->GetCharMaxLevelFromQGlobal();
|
||||
row["character_id"] = client->CharacterID();
|
||||
row["check_can_unsuspend_merc"] = client->CheckCanUnsuspendMerc();
|
||||
row["check_double_attack"] = client->CheckDoubleAttack();
|
||||
row["check_double_ranged_attack"] = client->CheckDoubleRangedAttack();
|
||||
row["check_dual_wield"] = client->CheckDualWield();
|
||||
row["check_trade_non_droppable"] = client->CheckTradeNonDroppable();
|
||||
row["check_triple_attack"] = client->CheckTripleAttack();
|
||||
row["client_max_level"] = client->GetClientMaxLevel();
|
||||
row["client_version_bit"] = client->ClientVersionBit();
|
||||
row["connected"] = client->Connected();
|
||||
row["copper"] = client->GetCopper();
|
||||
row["corpse_count"] = client->GetCorpseCount();
|
||||
row["duel_tar"] = client->GetDuelTarget();
|
||||
row["ebon_crystals"] = client->GetEbonCrystals();
|
||||
row["endurance"] = client->GetEndurance();
|
||||
row["endurance_percent"] = client->GetEndurancePercent();
|
||||
row["exp"] = client->GetEXP();
|
||||
row["face"] = client->GetFace();
|
||||
row["feigned"] = client->GetFeigned();
|
||||
row["gm"] = client->GetGM();
|
||||
row["gm_speed"] = client->GetGMSpeed();
|
||||
row["gold"] = client->GetGold();
|
||||
row["group_exp"] = client->GetGroupEXP();
|
||||
row["group_leadership_aa_health_enhancement"] = client->GroupLeadershipAAHealthEnhancement();
|
||||
row["group_leadership_aa_health_regeneration"] = client->GroupLeadershipAAHealthRegeneration();
|
||||
row["group_leadership_aa_mana_enhancement"] = client->GroupLeadershipAAManaEnhancement();
|
||||
row["group_leadership_aa_offense_enhancement"] = client->GroupLeadershipAAOffenseEnhancement();
|
||||
row["group_points"] = client->GetGroupPoints();
|
||||
row["guild_id"] = client->GuildID();
|
||||
row["guild_rank"] = client->GuildRank();
|
||||
row["has_adventure_data"] = client->HasAdventureData();
|
||||
row["hide_me"] = client->GetHideMe();
|
||||
row["horse_id"] = client->GetHorseId();
|
||||
row["hunger"] = client->GetHunger();
|
||||
row["hungry"] = client->Hungry();
|
||||
row["in_zone"] = client->InZone();
|
||||
row["instance_id"] = client->GetInstanceID();
|
||||
row["interrogate_inv_state"] = client->GetInterrogateInvState();
|
||||
row["ip"] = client->GetIP();
|
||||
row["is_become_npc"] = client->IsBecomeNPC();
|
||||
row["is_buyer"] = client->IsBuyer();
|
||||
row["is_dead"] = client->IsDead();
|
||||
row["is_dragging_corpse"] = client->IsDraggingCorpse();
|
||||
row["is_dueling"] = client->IsDueling();
|
||||
row["is_guild_banker"] = client->IsGuildBanker();
|
||||
row["is_hovering_for_respawn"] = client->IsHoveringForRespawn();
|
||||
row["is_in_a_guild"] = client->IsInAGuild();
|
||||
row["is_ld"] = client->IsLD();
|
||||
row["is_leadership_exp_on"] = client->IsLeadershipEXPOn();
|
||||
row["is_lfp"] = client->IsLFP();
|
||||
row["is_medding"] = client->IsMedding();
|
||||
row["is_on_adventure"] = client->IsOnAdventure();
|
||||
row["is_rezz_pending"] = client->IsRezzPending();
|
||||
row["is_sitting"] = client->IsSitting();
|
||||
row["is_starved"] = client->IsStarved();
|
||||
row["is_tracking"] = client->IsTracking();
|
||||
row["is_trader"] = client->IsTrader();
|
||||
row["is_unconscious"] = client->IsUnconscious();
|
||||
row["ldon_losses"] = client->GetLDoNLosses();
|
||||
row["ldon_wins"] = client->GetLDoNWins();
|
||||
row["last_inv_snapshot_time"] = client->GetLastInvSnapshotTime();
|
||||
row["last_name"] = client->GetLastName();
|
||||
row["level2"] = client->GetLevel2();
|
||||
row["level_regen"] = client->LevelRegen();
|
||||
row["ls_account_id"] = client->LSAccountID();
|
||||
row["max_endurance"] = client->GetMaxEndurance();
|
||||
row["max_x_tars"] = client->GetMaxXTargets();
|
||||
row["merc_id"] = client->GetMercID();
|
||||
row["merc_only_or_no_group"] = client->MercOnlyOrNoGroup();
|
||||
row["merc_slot"] = client->GetMercSlot();
|
||||
row["next_inv_snapshot_time"] = client->GetNextInvSnapshotTime();
|
||||
row["num_mercs"] = client->GetNumMercs();
|
||||
row["pending_adventure_create"] = client->GetPendingAdventureCreate();
|
||||
row["pending_adventure_door_click"] = client->GetPendingAdventureDoorClick();
|
||||
row["pending_adventure_leave"] = client->GetPendingAdventureLeave();
|
||||
row["pending_adventure_request"] = client->GetPendingAdventureRequest();
|
||||
row["pending_guild_invitation"] = client->GetPendingGuildInvitation();
|
||||
row["platinum"] = client->GetPlatinum();
|
||||
row["port"] = client->GetPort();
|
||||
row["primary_skill_value"] = client->GetPrimarySkillValue();
|
||||
row["proximity_x"] = client->ProximityX();
|
||||
row["proximity_y"] = client->ProximityY();
|
||||
row["proximity_z"] = client->ProximityZ();
|
||||
row["pvp_points"] = client->GetPVPPoints();
|
||||
row["radiant_crystals"] = client->GetRadiantCrystals();
|
||||
row["raid_exp"] = client->GetRaidEXP();
|
||||
row["raid_points"] = client->GetRaidPoints();
|
||||
row["raw_item_ac"] = client->GetRawItemAC();
|
||||
row["required_aa_experience"] = client->GetRequiredAAExperience();
|
||||
row["revoked"] = client->GetRevoked();
|
||||
row["run_mode"] = client->GetRunMode();
|
||||
row["save_currency"] = client->SaveCurrency();
|
||||
row["save_task_state"] = client->SaveTaskState();
|
||||
row["silver"] = client->GetSilver();
|
||||
row["skill_points"] = client->GetSkillPoints();
|
||||
row["spent_aa"] = client->GetSpentAA();
|
||||
row["tgb"] = client->TGB();
|
||||
row["thirst"] = client->GetThirst();
|
||||
row["thirsty"] = client->Thirsty();
|
||||
row["total_atk"] = client->GetTotalATK();
|
||||
row["total_seconds_played"] = client->GetTotalSecondsPlayed();
|
||||
row["weight"] = client->GetWeight();
|
||||
row["wid"] = client->GetWID();
|
||||
row["x_tarting_available"] = client->XTargettingAvailable();
|
||||
|
||||
response.append(row);
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
Json::Value ApiGetZoneAttributes(EQ::Net::WebsocketServerConnection *connection, Json::Value params)
|
||||
{
|
||||
if (zone->GetZoneID() == 0) {
|
||||
throw EQ::Net::WebsocketException("Zone must be loaded to invoke this call");
|
||||
}
|
||||
|
||||
Json::Value response;
|
||||
Json::Value row;
|
||||
|
||||
row["aggro_limit_reached"] = zone->AggroLimitReached();
|
||||
row["allow_mercs"] = zone->AllowMercs();
|
||||
row["buff_timers_suspended"] = zone->BuffTimersSuspended();
|
||||
row["can_bind"] = zone->CanBind();
|
||||
row["can_cast_outdoor"] = zone->CanCastOutdoor();
|
||||
row["can_do_combat"] = zone->CanDoCombat();
|
||||
row["can_levitate"] = zone->CanLevitate();
|
||||
row["count_auth"] = zone->CountAuth();
|
||||
row["count_spawn2"] = zone->CountSpawn2();
|
||||
row["file_name"] = zone->GetFileName();
|
||||
row["graveyard_id"] = zone->graveyard_id();
|
||||
row["graveyard_zoneid"] = zone->graveyard_zoneid();
|
||||
row["has_graveyard"] = zone->HasGraveyard();
|
||||
row["has_map"] = zone->HasMap();
|
||||
row["has_water_map"] = zone->HasWaterMap();
|
||||
row["has_weather"] = zone->HasWeather();
|
||||
row["instance_id"] = zone->GetInstanceID();
|
||||
row["instance_version"] = zone->GetInstanceVersion();
|
||||
row["instant_grids"] = zone->InstantGrids();
|
||||
row["is_city"] = zone->IsCity();
|
||||
row["is_hotzone"] = zone->IsHotzone();
|
||||
row["is_instance_persistent"] = zone->IsInstancePersistent();
|
||||
row["is_pvp_zone"] = zone->IsPVPZone();
|
||||
row["is_static_zone"] = zone->IsStaticZone();
|
||||
row["is_ucs_server_available"] = zone->IsUCSServerAvailable();
|
||||
row["long_name"] = zone->GetLongName();
|
||||
row["max_clients"] = zone->GetMaxClients();
|
||||
row["mobs_aggro_count"] = zone->MobsAggroCount();
|
||||
row["save_zone_cfg"] = zone->SaveZoneCFG();
|
||||
row["short_name"] = zone->GetShortName();
|
||||
row["total_blocked_spells"] = zone->GetTotalBlockedSpells();
|
||||
row["zone_id"] = zone->GetZoneID();
|
||||
row["zone_type"] = zone->GetZoneType();
|
||||
|
||||
response.append(row);
|
||||
return response;
|
||||
}
|
||||
|
||||
Json::Value ApiGetLogsysCategories(EQ::Net::WebsocketServerConnection *connection, Json::Value params)
|
||||
{
|
||||
if (zone->GetZoneID() == 0) {
|
||||
throw EQ::Net::WebsocketException("Zone must be loaded to invoke this call");
|
||||
}
|
||||
|
||||
Json::Value response;
|
||||
|
||||
for (int i = 1; i < Logs::LogCategory::MaxCategoryID; i++) {
|
||||
Json::Value row;
|
||||
|
||||
row["log_category_id"] = i;
|
||||
row["log_category_description"] = Logs::LogCategoryName[i];
|
||||
row["log_to_console"] = LogSys.log_settings[i].log_to_console;
|
||||
row["log_to_file"] = LogSys.log_settings[i].log_to_file;
|
||||
row["log_to_gmsay"] = LogSys.log_settings[i].log_to_gmsay;
|
||||
|
||||
response.append(row);
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
Json::Value ApiSetLoggingLevel(EQ::Net::WebsocketServerConnection *connection, Json::Value params)
|
||||
{
|
||||
if (zone->GetZoneID() == 0) {
|
||||
throw EQ::Net::WebsocketException("Zone must be loaded to invoke this call");
|
||||
}
|
||||
|
||||
Json::Value response;
|
||||
|
||||
auto logging_category = params[0].asInt();
|
||||
auto logging_level = params[1].asInt();
|
||||
|
||||
response["status"] = "Category doesn't exist";
|
||||
|
||||
Log(Logs::General, Logs::Status, "Logging category is %i and level is %i",
|
||||
logging_category,
|
||||
logging_level
|
||||
);
|
||||
|
||||
if (logging_category < Logs::LogCategory::MaxCategoryID &&
|
||||
logging_category > Logs::LogCategory::None
|
||||
) {
|
||||
LogSys.log_settings[logging_category].log_to_console = logging_level;
|
||||
response["status"] = "Category log level updated";
|
||||
}
|
||||
|
||||
if (logging_level > 0) {
|
||||
LogSys.log_settings[logging_category].is_category_enabled = 1;
|
||||
}
|
||||
else {
|
||||
LogSys.log_settings[logging_category].is_category_enabled = 0;
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
void RegisterApiLogEvent(std::unique_ptr<EQ::Net::WebsocketServer> &server)
|
||||
{
|
||||
LogSys.SetConsoleHandler(
|
||||
[&](uint16 debug_level, uint16 log_category, const std::string &msg) {
|
||||
Json::Value data;
|
||||
data["debug_level"] = debug_level;
|
||||
data["log_category"] = log_category;
|
||||
data["msg"] = msg;
|
||||
server->DispatchEvent(EQ::Net::SubscriptionEventLog, data, 50);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void RegisterApiService(std::unique_ptr<EQ::Net::WebsocketServer> &server)
|
||||
{
|
||||
server->SetLoginHandler(CheckLogin);
|
||||
server->SetMethodHandler("get_packet_statistics", &ApiGetPacketStatistics, 50);
|
||||
server->SetMethodHandler("get_opcode_list", &ApiGetOpcodeList, 50);
|
||||
server->SetMethodHandler("get_npc_list_detail", &ApiGetNpcListDetail, 50);
|
||||
server->SetMethodHandler("get_door_list_detail", &ApiGetDoorListDetail, 50);
|
||||
server->SetMethodHandler("get_corpse_list_detail", &ApiGetCorpseListDetail, 50);
|
||||
server->SetMethodHandler("get_object_list_detail", &ApiGetObjectListDetail, 50);
|
||||
server->SetMethodHandler("get_mob_list_detail", &ApiGetMobListDetail, 50);
|
||||
server->SetMethodHandler("get_client_list_detail", &ApiGetClientListDetail, 50);
|
||||
server->SetMethodHandler("get_zone_attributes", &ApiGetZoneAttributes, 50);
|
||||
server->SetMethodHandler("get_logsys_categories", &ApiGetLogsysCategories, 50);
|
||||
server->SetMethodHandler("set_logging_level", &ApiSetLoggingLevel, 50);
|
||||
|
||||
RegisterApiLogEvent(server);
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* EQEmulator: Everquest Server Emulator
|
||||
* Copyright (C) 2001-2019 EQEmulator Development Team (https://github.com/EQEmu/Server)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
* are required to give you total support for your newly bought product;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include "../common/net/websocket_server.h"
|
||||
|
||||
void RegisterApiService(std::unique_ptr<EQ::Net::WebsocketServer> &server);
|
||||
+3
-1
@@ -4514,7 +4514,9 @@ void Mob::ApplyMeleeDamageMods(uint16 skill, int &damage, Mob *defender, ExtraAt
|
||||
if (defender->IsClient() && defender->GetClass() == WARRIOR)
|
||||
dmgbonusmod -= 5;
|
||||
// 168 defensive
|
||||
dmgbonusmod += (defender->spellbonuses.MeleeMitigationEffect + itembonuses.MeleeMitigationEffect + aabonuses.MeleeMitigationEffect);
|
||||
dmgbonusmod += (defender->spellbonuses.MeleeMitigationEffect +
|
||||
defender->itembonuses.MeleeMitigationEffect +
|
||||
defender->aabonuses.MeleeMitigationEffect);
|
||||
}
|
||||
|
||||
damage += damage * dmgbonusmod / 100;
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@
|
||||
|
||||
Aura::Aura(NPCType *type_data, Mob *owner, AuraRecord &record)
|
||||
: NPC(type_data, 0, owner->GetPosition(), GravityBehavior::Flying), spell_id(record.spell_id), distance(record.distance),
|
||||
remove_timer(record.duration), movement_timer(100), process_timer(100), aura_id(-1)
|
||||
remove_timer(record.duration), movement_timer(100), process_timer(1000), aura_id(-1)
|
||||
{
|
||||
GiveNPCTypeData(type_data); // we will delete this later on
|
||||
m_owner = owner->GetID();
|
||||
|
||||
+1
-1
@@ -56,7 +56,7 @@ Beacon::Beacon(Mob *at_mob, int lifetime)
|
||||
:Mob
|
||||
(
|
||||
nullptr, nullptr, 0, 0, 0, INVISIBLE_MAN, 0, BT_NoTarget, 0, 0, 0, 0, 0, at_mob->GetPosition(), 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, EQEmu::TintProfile(), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, EQEmu::TintProfile(), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
),
|
||||
remove_timer(lifetime),
|
||||
spell_timer(0)
|
||||
|
||||
+11
-2
@@ -1472,6 +1472,17 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon)
|
||||
newbon->trap_slots += base1;
|
||||
break;
|
||||
|
||||
case SE_ForageSkill:
|
||||
newbon->GrantForage += base1;
|
||||
// we need to grant a skill point here
|
||||
// I'd rather not do this here, but whatever, probably fine
|
||||
if (IsClient()) {
|
||||
auto client = CastToClient();
|
||||
if (client->GetRawSkill(EQEmu::skills::SkillType::SkillForage) == 0)
|
||||
client->SetSkill(EQEmu::skills::SkillType::SkillForage, 1);
|
||||
}
|
||||
break;
|
||||
|
||||
// to do
|
||||
case SE_PetDiscipline:
|
||||
break;
|
||||
@@ -1479,8 +1490,6 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon)
|
||||
break;
|
||||
case SE_BandolierSlots:
|
||||
break;
|
||||
case SE_ForageSkill:
|
||||
break;
|
||||
case SE_SecondaryForte:
|
||||
break;
|
||||
case SE_ExtendedShielding:
|
||||
|
||||
+385
-215
@@ -29,7 +29,9 @@
|
||||
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(), Ground, false), rest_timer(1) {
|
||||
Bot::Bot(NPCType *npcTypeData, Client* botOwner) : NPC(npcTypeData, nullptr, glm::vec4(), Ground, false), rest_timer(1), ping_timer(1) {
|
||||
GiveNPCTypeData(npcTypeData);
|
||||
|
||||
if(botOwner) {
|
||||
this->SetBotOwner(botOwner);
|
||||
this->_botOwnerCharacterID = botOwner->CharacterID();
|
||||
@@ -46,23 +48,23 @@ Bot::Bot(NPCType npcTypeData, Client* botOwner) : NPC(&npcTypeData, nullptr, glm
|
||||
_lastTotalPlayTime = 0;
|
||||
_startTotalPlayTime = time(&_startTotalPlayTime);
|
||||
_lastZoneId = 0;
|
||||
_baseMR = npcTypeData.MR;
|
||||
_baseCR = npcTypeData.CR;
|
||||
_baseDR = npcTypeData.DR;
|
||||
_baseFR = npcTypeData.FR;
|
||||
_basePR = npcTypeData.PR;
|
||||
_baseCorrup = npcTypeData.Corrup;
|
||||
_baseAC = npcTypeData.AC;
|
||||
_baseSTR = npcTypeData.STR;
|
||||
_baseSTA = npcTypeData.STA;
|
||||
_baseDEX = npcTypeData.DEX;
|
||||
_baseAGI = npcTypeData.AGI;
|
||||
_baseINT = npcTypeData.INT;
|
||||
_baseWIS = npcTypeData.WIS;
|
||||
_baseCHA = npcTypeData.CHA;
|
||||
_baseATK = npcTypeData.ATK;
|
||||
_baseRace = npcTypeData.race;
|
||||
_baseGender = npcTypeData.gender;
|
||||
_baseMR = npcTypeData->MR;
|
||||
_baseCR = npcTypeData->CR;
|
||||
_baseDR = npcTypeData->DR;
|
||||
_baseFR = npcTypeData->FR;
|
||||
_basePR = npcTypeData->PR;
|
||||
_baseCorrup = npcTypeData->Corrup;
|
||||
_baseAC = npcTypeData->AC;
|
||||
_baseSTR = npcTypeData->STR;
|
||||
_baseSTA = npcTypeData->STA;
|
||||
_baseDEX = npcTypeData->DEX;
|
||||
_baseAGI = npcTypeData->AGI;
|
||||
_baseINT = npcTypeData->INT;
|
||||
_baseWIS = npcTypeData->WIS;
|
||||
_baseCHA = npcTypeData->CHA;
|
||||
_baseATK = npcTypeData->ATK;
|
||||
_baseRace = npcTypeData->race;
|
||||
_baseGender = npcTypeData->gender;
|
||||
RestRegenHP = 0;
|
||||
RestRegenMana = 0;
|
||||
RestRegenEndurance = 0;
|
||||
@@ -80,6 +82,7 @@ Bot::Bot(NPCType npcTypeData, Client* botOwner) : NPC(&npcTypeData, nullptr, glm
|
||||
SetShowHelm(true);
|
||||
SetPauseAI(false);
|
||||
rest_timer.Disable();
|
||||
ping_timer.Disable();
|
||||
SetFollowDistance(BOT_FOLLOW_DISTANCE_DEFAULT);
|
||||
if (IsCasterClass(GetClass()))
|
||||
SetStopMeleeLevel((uint8)RuleI(Bots, CasterStopMeleeLevel));
|
||||
@@ -104,9 +107,11 @@ Bot::Bot(NPCType npcTypeData, Client* botOwner) : NPC(&npcTypeData, nullptr, glm
|
||||
}
|
||||
|
||||
// This constructor is used when the bot is loaded out of the database
|
||||
Bot::Bot(uint32 botID, uint32 botOwnerCharacterID, uint32 botSpellsID, double totalPlayTime, uint32 lastZoneId, NPCType npcTypeData)
|
||||
: NPC(&npcTypeData, nullptr, glm::vec4(), Ground, false), rest_timer(1)
|
||||
Bot::Bot(uint32 botID, uint32 botOwnerCharacterID, uint32 botSpellsID, double totalPlayTime, uint32 lastZoneId, NPCType *npcTypeData)
|
||||
: NPC(npcTypeData, nullptr, glm::vec4(), Ground, false), rest_timer(1), ping_timer(1)
|
||||
{
|
||||
GiveNPCTypeData(npcTypeData);
|
||||
|
||||
this->_botOwnerCharacterID = botOwnerCharacterID;
|
||||
if(this->_botOwnerCharacterID > 0)
|
||||
this->SetBotOwner(entity_list.GetClientByCharID(this->_botOwnerCharacterID));
|
||||
@@ -122,25 +127,25 @@ Bot::Bot(uint32 botID, uint32 botOwnerCharacterID, uint32 botSpellsID, double to
|
||||
_startTotalPlayTime = time(&_startTotalPlayTime);
|
||||
_lastZoneId = lastZoneId;
|
||||
berserk = false;
|
||||
_baseMR = npcTypeData.MR;
|
||||
_baseCR = npcTypeData.CR;
|
||||
_baseDR = npcTypeData.DR;
|
||||
_baseFR = npcTypeData.FR;
|
||||
_basePR = npcTypeData.PR;
|
||||
_baseCorrup = npcTypeData.Corrup;
|
||||
_baseAC = npcTypeData.AC;
|
||||
_baseSTR = npcTypeData.STR;
|
||||
_baseSTA = npcTypeData.STA;
|
||||
_baseDEX = npcTypeData.DEX;
|
||||
_baseAGI = npcTypeData.AGI;
|
||||
_baseINT = npcTypeData.INT;
|
||||
_baseWIS = npcTypeData.WIS;
|
||||
_baseCHA = npcTypeData.CHA;
|
||||
_baseATK = npcTypeData.ATK;
|
||||
_baseRace = npcTypeData.race;
|
||||
_baseGender = npcTypeData.gender;
|
||||
current_hp = npcTypeData.current_hp;
|
||||
current_mana = npcTypeData.Mana;
|
||||
_baseMR = npcTypeData->MR;
|
||||
_baseCR = npcTypeData->CR;
|
||||
_baseDR = npcTypeData->DR;
|
||||
_baseFR = npcTypeData->FR;
|
||||
_basePR = npcTypeData->PR;
|
||||
_baseCorrup = npcTypeData->Corrup;
|
||||
_baseAC = npcTypeData->AC;
|
||||
_baseSTR = npcTypeData->STR;
|
||||
_baseSTA = npcTypeData->STA;
|
||||
_baseDEX = npcTypeData->DEX;
|
||||
_baseAGI = npcTypeData->AGI;
|
||||
_baseINT = npcTypeData->INT;
|
||||
_baseWIS = npcTypeData->WIS;
|
||||
_baseCHA = npcTypeData->CHA;
|
||||
_baseATK = npcTypeData->ATK;
|
||||
_baseRace = npcTypeData->race;
|
||||
_baseGender = npcTypeData->gender;
|
||||
current_hp = npcTypeData->current_hp;
|
||||
current_mana = npcTypeData->Mana;
|
||||
RestRegenHP = 0;
|
||||
RestRegenMana = 0;
|
||||
RestRegenEndurance = 0;
|
||||
@@ -153,15 +158,16 @@ Bot::Bot(uint32 botID, uint32 botOwnerCharacterID, uint32 botSpellsID, double to
|
||||
SetRangerAutoWeaponSelect(false);
|
||||
|
||||
bool stance_flag = false;
|
||||
if (!botdb.LoadStance(this, stance_flag) && bot_owner)
|
||||
if (!database.botdb.LoadStance(this, stance_flag) && bot_owner)
|
||||
bot_owner->Message(13, "%s for '%s'", BotDatabase::fail::LoadStance(), GetCleanName());
|
||||
if (!stance_flag && bot_owner)
|
||||
bot_owner->Message(13, "Could not locate stance for '%s'", GetCleanName());
|
||||
|
||||
SetTaunting((GetClass() == WARRIOR || GetClass() == PALADIN || GetClass() == SHADOWKNIGHT) && (GetBotStance() == BotStanceAggressive));
|
||||
SetTaunting((GetClass() == WARRIOR || GetClass() == PALADIN || GetClass() == SHADOWKNIGHT) && (GetBotStance() == EQEmu::constants::stanceAggressive));
|
||||
SetPauseAI(false);
|
||||
|
||||
rest_timer.Disable();
|
||||
ping_timer.Disable();
|
||||
SetFollowDistance(BOT_FOLLOW_DISTANCE_DEFAULT);
|
||||
if (IsCasterClass(GetClass()))
|
||||
SetStopMeleeLevel((uint8)RuleI(Bots, CasterStopMeleeLevel));
|
||||
@@ -171,10 +177,10 @@ Bot::Bot(uint32 botID, uint32 botOwnerCharacterID, uint32 botSpellsID, double to
|
||||
strcpy(this->name, this->GetCleanName());
|
||||
|
||||
memset(&_botInspectMessage, 0, sizeof(InspectMessage_Struct));
|
||||
if (!botdb.LoadInspectMessage(GetBotID(), _botInspectMessage) && bot_owner)
|
||||
if (!database.botdb.LoadInspectMessage(GetBotID(), _botInspectMessage) && bot_owner)
|
||||
bot_owner->Message(13, "%s for '%s'", BotDatabase::fail::LoadInspectMessage(), GetCleanName());
|
||||
|
||||
if (!botdb.LoadGuildMembership(GetBotID(), _guildId, _guildRank, _guildName) && bot_owner)
|
||||
if (!database.botdb.LoadGuildMembership(GetBotID(), _guildId, _guildRank, _guildName) && bot_owner)
|
||||
bot_owner->Message(13, "%s for '%s'", BotDatabase::fail::LoadGuildMembership(), GetCleanName());
|
||||
|
||||
std::string error_message;
|
||||
@@ -199,12 +205,12 @@ Bot::Bot(uint32 botID, uint32 botOwnerCharacterID, uint32 botSpellsID, double to
|
||||
|
||||
GenerateBaseStats();
|
||||
|
||||
if (!botdb.LoadTimers(this) && bot_owner)
|
||||
if (!database.botdb.LoadTimers(this) && bot_owner)
|
||||
bot_owner->Message(13, "%s for '%s'", BotDatabase::fail::LoadTimers(), GetCleanName());
|
||||
|
||||
LoadAAs();
|
||||
|
||||
if (!botdb.LoadBuffs(this) && bot_owner)
|
||||
if (!database.botdb.LoadBuffs(this) && bot_owner)
|
||||
bot_owner->Message(13, "&s for '%s'", BotDatabase::fail::LoadBuffs(), GetCleanName());
|
||||
|
||||
CalcBotStats(false);
|
||||
@@ -313,112 +319,253 @@ bool Bot::IsStanding() {
|
||||
return result;
|
||||
}
|
||||
|
||||
NPCType Bot::FillNPCTypeStruct(uint32 botSpellsID, std::string botName, std::string botLastName, uint8 botLevel, uint16 botRace, uint8 botClass, uint8 gender, float size, uint32 face, uint32 hairStyle, uint32 hairColor, uint32 eyeColor, uint32 eyeColor2, uint32 beardColor, uint32 beard, uint32 drakkinHeritage, uint32 drakkinTattoo, uint32 drakkinDetails, int32 hp, int32 mana, int32 mr, int32 cr, int32 dr, int32 fr, int32 pr, int32 corrup, int32 ac, uint32 str, uint32 sta, uint32 dex, uint32 agi, uint32 _int, uint32 wis, uint32 cha, uint32 attack) {
|
||||
NPCType BotNPCType;
|
||||
int CopyLength = 0;
|
||||
CopyLength = botName.copy(BotNPCType.name, 63);
|
||||
BotNPCType.name[CopyLength] = '\0';
|
||||
CopyLength = 0;
|
||||
CopyLength = botLastName.copy(BotNPCType.lastname, 69);
|
||||
BotNPCType.lastname[CopyLength] = '\0';
|
||||
CopyLength = 0;
|
||||
BotNPCType.npc_spells_id = botSpellsID;
|
||||
BotNPCType.level = botLevel;
|
||||
BotNPCType.race = botRace;
|
||||
BotNPCType.class_ = botClass;
|
||||
BotNPCType.gender = gender;
|
||||
BotNPCType.size = size;
|
||||
BotNPCType.luclinface = face;
|
||||
BotNPCType.hairstyle = hairStyle;
|
||||
BotNPCType.haircolor = hairColor;
|
||||
BotNPCType.eyecolor1 = eyeColor;
|
||||
BotNPCType.eyecolor2 = eyeColor2;
|
||||
BotNPCType.beardcolor = beardColor;
|
||||
BotNPCType.beard = beard;
|
||||
BotNPCType.drakkin_heritage = drakkinHeritage;
|
||||
BotNPCType.drakkin_tattoo = drakkinTattoo;
|
||||
BotNPCType.drakkin_details = drakkinDetails;
|
||||
BotNPCType.current_hp = hp;
|
||||
BotNPCType.Mana = mana;
|
||||
BotNPCType.MR = mr;
|
||||
BotNPCType.CR = cr;
|
||||
BotNPCType.DR = dr;
|
||||
BotNPCType.FR = fr;
|
||||
BotNPCType.PR = pr;
|
||||
BotNPCType.Corrup = corrup;
|
||||
BotNPCType.AC = ac;
|
||||
BotNPCType.STR = str;
|
||||
BotNPCType.STA = sta;
|
||||
BotNPCType.DEX = dex;
|
||||
BotNPCType.AGI = agi;
|
||||
BotNPCType.INT = _int;
|
||||
BotNPCType.WIS = wis;
|
||||
BotNPCType.CHA = cha;
|
||||
BotNPCType.ATK = attack;
|
||||
BotNPCType.npc_id = 0;
|
||||
BotNPCType.texture = 0;
|
||||
BotNPCType.d_melee_texture1 = 0;
|
||||
BotNPCType.d_melee_texture2 = 0;
|
||||
BotNPCType.qglobal = false;
|
||||
BotNPCType.attack_speed = 0;
|
||||
BotNPCType.runspeed = 0.7f;
|
||||
BotNPCType.bodytype = 1;
|
||||
BotNPCType.findable = 0;
|
||||
BotNPCType.hp_regen = 1;
|
||||
BotNPCType.mana_regen = 1;
|
||||
BotNPCType.maxlevel = botLevel;
|
||||
BotNPCType.light = 0; // due to the way that bots are coded..this is sent post-spawn
|
||||
return BotNPCType;
|
||||
NPCType *Bot::FillNPCTypeStruct(uint32 botSpellsID, std::string botName, std::string botLastName, uint8 botLevel, uint16 botRace, uint8 botClass, uint8 gender, float size, uint32 face, uint32 hairStyle, uint32 hairColor, uint32 eyeColor, uint32 eyeColor2, uint32 beardColor, uint32 beard, uint32 drakkinHeritage, uint32 drakkinTattoo, uint32 drakkinDetails, int32 hp, int32 mana, int32 mr, int32 cr, int32 dr, int32 fr, int32 pr, int32 corrup, int32 ac, uint32 str, uint32 sta, uint32 dex, uint32 agi, uint32 _int, uint32 wis, uint32 cha, uint32 attack) {
|
||||
auto bot_npc_type = new NPCType{ 0 };
|
||||
int copy_length = 0;
|
||||
|
||||
copy_length = botName.copy(bot_npc_type->name, 63);
|
||||
bot_npc_type->name[copy_length] = '\0';
|
||||
copy_length = 0;
|
||||
|
||||
copy_length = botLastName.copy(bot_npc_type->lastname, 69);
|
||||
bot_npc_type->lastname[copy_length] = '\0';
|
||||
copy_length = 0;
|
||||
|
||||
bot_npc_type->current_hp = hp;
|
||||
bot_npc_type->max_hp = hp;
|
||||
bot_npc_type->size = size;
|
||||
bot_npc_type->runspeed = 0.7f;
|
||||
bot_npc_type->gender = gender;
|
||||
bot_npc_type->race = botRace;
|
||||
bot_npc_type->class_ = botClass;
|
||||
bot_npc_type->bodytype = 1;
|
||||
bot_npc_type->deity = EQEmu::deity::DeityAgnostic;
|
||||
bot_npc_type->level = botLevel;
|
||||
//bot_npc_type->npc_id = 0;
|
||||
//bot_npc_type->texture = 0;
|
||||
//bot_npc_type->helmtexture = 0;
|
||||
//bot_npc_type->herosforgemodel = 0;
|
||||
//bot_npc_type->loottable_id = 0;
|
||||
bot_npc_type->npc_spells_id = botSpellsID;
|
||||
//bot_npc_type->npc_spells_effects_id = 0;
|
||||
//bot_npc_type->npc_faction_id = 0;
|
||||
//bot_npc_type->merchanttype = 0;
|
||||
//bot_npc_type->alt_currency_type = 0;
|
||||
//bot_npc_type->adventure_template = 0;
|
||||
//bot_npc_type->trap_template = 0;
|
||||
//bot_npc_type->light = 0;
|
||||
bot_npc_type->AC = ac;
|
||||
bot_npc_type->Mana = mana;
|
||||
bot_npc_type->ATK = attack;
|
||||
bot_npc_type->STR = str;
|
||||
bot_npc_type->STA = sta;
|
||||
bot_npc_type->DEX = dex;
|
||||
bot_npc_type->AGI = agi;
|
||||
bot_npc_type->INT = _int;
|
||||
bot_npc_type->WIS = wis;
|
||||
bot_npc_type->CHA = cha;
|
||||
bot_npc_type->MR = mr;
|
||||
bot_npc_type->FR = fr;
|
||||
bot_npc_type->CR = cr;
|
||||
bot_npc_type->PR = pr;
|
||||
bot_npc_type->DR = dr;
|
||||
bot_npc_type->Corrup = corrup;
|
||||
//bot_npc_type->PhR = 0;
|
||||
bot_npc_type->haircolor = hairColor;
|
||||
bot_npc_type->beardcolor = beardColor;
|
||||
bot_npc_type->eyecolor1 = eyeColor;
|
||||
bot_npc_type->eyecolor2 = eyeColor2;
|
||||
bot_npc_type->hairstyle = hairStyle;
|
||||
bot_npc_type->luclinface = face;
|
||||
bot_npc_type->beard = beard;
|
||||
bot_npc_type->drakkin_heritage = drakkinHeritage;
|
||||
bot_npc_type->drakkin_tattoo = drakkinTattoo;
|
||||
bot_npc_type->drakkin_details = drakkinDetails;
|
||||
//bot_npc_type->armor_tint = { 0 };
|
||||
//bot_npc_type->min_dmg = 0;
|
||||
//bot_npc_type->max_dmg = 0;
|
||||
//bot_npc_type->charm_ac = 0;
|
||||
//bot_npc_type->charm_min_dmg = 0;
|
||||
//bot_npc_type->charm_max_dmg = 0;
|
||||
//bot_npc_type->charm_attack_delay = 0;
|
||||
//bot_npc_type->charm_accuracy_rating = 0;
|
||||
//bot_npc_type->charm_avoidance_rating = 0;
|
||||
//bot_npc_type->charm_atk = 0;
|
||||
//bot_npc_type->attack_count = 0;
|
||||
//*bot_npc_type->special_abilities = { 0 };
|
||||
//bot_npc_type->d_melee_texture1 = 0;
|
||||
//bot_npc_type->d_melee_texture2 = 0;
|
||||
//*bot_npc_type->ammo_idfile = { 0 };
|
||||
//bot_npc_type->prim_melee_type = 0;
|
||||
//bot_npc_type->sec_melee_type = 0;
|
||||
//bot_npc_type->ranged_type = 0;
|
||||
bot_npc_type->hp_regen = 1;
|
||||
bot_npc_type->mana_regen = 1;
|
||||
//bot_npc_type->aggroradius = 0;
|
||||
//bot_npc_type->assistradius = 0;
|
||||
//bot_npc_type->see_invis = 0;
|
||||
//bot_npc_type->see_invis_undead = false;
|
||||
//bot_npc_type->see_hide = false;
|
||||
//bot_npc_type->see_improved_hide = false;
|
||||
//bot_npc_type->qglobal = false;
|
||||
//bot_npc_type->npc_aggro = false;
|
||||
//bot_npc_type->spawn_limit = 0;
|
||||
//bot_npc_type->mount_color = 0;
|
||||
//bot_npc_type->attack_speed = 0.0f;
|
||||
//bot_npc_type->attack_delay = 0;
|
||||
//bot_npc_type->accuracy_rating = 0;
|
||||
//bot_npc_type->avoidance_rating = 0;
|
||||
//bot_npc_type->findable = false;
|
||||
bot_npc_type->trackable = true;
|
||||
//bot_npc_type->slow_mitigation = 0;
|
||||
bot_npc_type->maxlevel = botLevel;
|
||||
//bot_npc_type->scalerate = 0;
|
||||
//bot_npc_type->private_corpse = false;
|
||||
//bot_npc_type->unique_spawn_by_name = false;
|
||||
//bot_npc_type->underwater = false;
|
||||
//bot_npc_type->emoteid = 0;
|
||||
//bot_npc_type->spellscale = 0.0f;
|
||||
//bot_npc_type->healscale = 0.0f;
|
||||
//bot_npc_type->no_target_hotkey = false;
|
||||
//bot_npc_type->raid_target = false;
|
||||
//bot_npc_type->armtexture = 0;
|
||||
//bot_npc_type->bracertexture = 0;
|
||||
//bot_npc_type->handtexture = 0;
|
||||
//bot_npc_type->legtexture = 0;
|
||||
//bot_npc_type->feettexture = 0;
|
||||
//bot_npc_type->ignore_despawn = false;
|
||||
bot_npc_type->show_name = true;
|
||||
//bot_npc_type->untargetable = false;
|
||||
bot_npc_type->skip_global_loot = true;
|
||||
//bot_npc_type->rare_spawn = false;
|
||||
bot_npc_type->stuck_behavior = Ground;
|
||||
bot_npc_type->skip_auto_scale = true;
|
||||
|
||||
return bot_npc_type;
|
||||
}
|
||||
|
||||
NPCType Bot::CreateDefaultNPCTypeStructForBot(std::string botName, std::string botLastName, uint8 botLevel, uint16 botRace, uint8 botClass, uint8 gender) {
|
||||
NPCType Result;
|
||||
int CopyLength = 0;
|
||||
CopyLength = botName.copy(Result.name, 63);
|
||||
Result.name[CopyLength] = '\0';
|
||||
CopyLength = 0;
|
||||
CopyLength = botLastName.copy(Result.lastname, 69);
|
||||
Result.lastname[CopyLength] = '\0';
|
||||
CopyLength = 0;
|
||||
Result.level = botLevel;
|
||||
Result.race = botRace;
|
||||
Result.class_ = botClass;
|
||||
Result.gender = gender;
|
||||
// default values
|
||||
Result.maxlevel = botLevel;
|
||||
Result.size = 6.0;
|
||||
Result.npc_id = 0;
|
||||
Result.current_hp = 0;
|
||||
Result.drakkin_details = 0;
|
||||
Result.drakkin_heritage = 0;
|
||||
Result.drakkin_tattoo = 0;
|
||||
Result.runspeed = 0.7f;
|
||||
Result.bodytype = 1;
|
||||
Result.findable = 0;
|
||||
Result.hp_regen = 1;
|
||||
Result.mana_regen = 1;
|
||||
Result.texture = 0;
|
||||
Result.d_melee_texture1 = 0;
|
||||
Result.d_melee_texture2 = 0;
|
||||
Result.qglobal = false;
|
||||
Result.npc_spells_id = 0;
|
||||
Result.attack_speed = 0;
|
||||
Result.STR = 75;
|
||||
Result.STA = 75;
|
||||
Result.DEX = 75;
|
||||
Result.AGI = 75;
|
||||
Result.WIS = 75;
|
||||
Result.INT = 75;
|
||||
Result.CHA = 75;
|
||||
Result.ATK = 75;
|
||||
Result.MR = 25;
|
||||
Result.FR = 25;
|
||||
Result.DR = 15;
|
||||
Result.PR = 15;
|
||||
Result.CR = 25;
|
||||
Result.Corrup = 15;
|
||||
Result.AC = 12;
|
||||
return Result;
|
||||
NPCType *Bot::CreateDefaultNPCTypeStructForBot(std::string botName, std::string botLastName, uint8 botLevel, uint16 botRace, uint8 botClass, uint8 gender) {
|
||||
auto bot_npc_type = new NPCType{ 0 };
|
||||
int copy_length = 0;
|
||||
|
||||
copy_length = botName.copy(bot_npc_type->name, 63);
|
||||
bot_npc_type->name[copy_length] = '\0';
|
||||
copy_length = 0;
|
||||
|
||||
copy_length = botLastName.copy(bot_npc_type->lastname, 69);
|
||||
bot_npc_type->lastname[copy_length] = '\0';
|
||||
copy_length = 0;
|
||||
|
||||
//bot_npc_type->current_hp = 0;
|
||||
//bot_npc_type->max_hp = 0;
|
||||
bot_npc_type->size = 6.0f;
|
||||
bot_npc_type->runspeed = 0.7f;
|
||||
bot_npc_type->gender = gender;
|
||||
bot_npc_type->race = botRace;
|
||||
bot_npc_type->class_ = botClass;
|
||||
bot_npc_type->bodytype = 1;
|
||||
bot_npc_type->deity = EQEmu::deity::DeityAgnostic;
|
||||
bot_npc_type->level = botLevel;
|
||||
//bot_npc_type->npc_id = 0;
|
||||
//bot_npc_type->texture = 0;
|
||||
//bot_npc_type->helmtexture = 0;
|
||||
//bot_npc_type->herosforgemodel = 0;
|
||||
//bot_npc_type->loottable_id = 0;
|
||||
//bot_npc_type->npc_spells_id = 0;
|
||||
//bot_npc_type->npc_spells_effects_id = 0;
|
||||
//bot_npc_type->npc_faction_id = 0;
|
||||
//bot_npc_type->merchanttype = 0;
|
||||
//bot_npc_type->alt_currency_type = 0;
|
||||
//bot_npc_type->adventure_template = 0;
|
||||
//bot_npc_type->trap_template = 0;
|
||||
//bot_npc_type->light = 0;
|
||||
bot_npc_type->AC = 12;
|
||||
//bot_npc_type->Mana = 0;
|
||||
bot_npc_type->ATK = 75;
|
||||
bot_npc_type->STR = 75;
|
||||
bot_npc_type->STA = 75;
|
||||
bot_npc_type->DEX = 75;
|
||||
bot_npc_type->AGI = 75;
|
||||
bot_npc_type->INT = 75;
|
||||
bot_npc_type->WIS = 75;
|
||||
bot_npc_type->CHA = 75;
|
||||
bot_npc_type->MR = 25;
|
||||
bot_npc_type->FR = 25;
|
||||
bot_npc_type->CR = 25;
|
||||
bot_npc_type->PR = 15;
|
||||
bot_npc_type->DR = 15;
|
||||
bot_npc_type->Corrup = 15;
|
||||
//bot_npc_type->PhR = 0;
|
||||
//bot_npc_type->haircolor = 0;
|
||||
//bot_npc_type->beardcolor = 0;
|
||||
//bot_npc_type->eyecolor1 = 0;
|
||||
//bot_npc_type->eyecolor2 = 0;
|
||||
//bot_npc_type->hairstyle = 0;
|
||||
//bot_npc_type->luclinface = 0;
|
||||
//bot_npc_type->beard = 0;
|
||||
//bot_npc_type->drakkin_heritage = 0;
|
||||
//bot_npc_type->drakkin_tattoo = 0;
|
||||
//bot_npc_type->drakkin_details = 0;
|
||||
//bot_npc_type->armor_tint = { 0 };
|
||||
//bot_npc_type->min_dmg = 0;
|
||||
//bot_npc_type->max_dmg = 0;
|
||||
//bot_npc_type->charm_ac = 0;
|
||||
//bot_npc_type->charm_min_dmg = 0;
|
||||
//bot_npc_type->charm_max_dmg = 0;
|
||||
//bot_npc_type->charm_attack_delay = 0;
|
||||
//bot_npc_type->charm_accuracy_rating = 0;
|
||||
//bot_npc_type->charm_avoidance_rating = 0;
|
||||
//bot_npc_type->charm_atk = 0;
|
||||
//bot_npc_type->attack_count = 0;
|
||||
//*bot_npc_type->special_abilities = { 0 };
|
||||
//bot_npc_type->d_melee_texture1 = 0;
|
||||
//bot_npc_type->d_melee_texture2 = 0;
|
||||
//*bot_npc_type->ammo_idfile = { 0 };
|
||||
//bot_npc_type->prim_melee_type = 0;
|
||||
//bot_npc_type->sec_melee_type = 0;
|
||||
//bot_npc_type->ranged_type = 0;
|
||||
bot_npc_type->hp_regen = 1;
|
||||
bot_npc_type->mana_regen = 1;
|
||||
//bot_npc_type->aggroradius = 0;
|
||||
//bot_npc_type->assistradius = 0;
|
||||
//bot_npc_type->see_invis = 0;
|
||||
//bot_npc_type->see_invis_undead = false;
|
||||
//bot_npc_type->see_hide = false;
|
||||
//bot_npc_type->see_improved_hide = false;
|
||||
//bot_npc_type->qglobal = false;
|
||||
//bot_npc_type->npc_aggro = false;
|
||||
//bot_npc_type->spawn_limit = 0;
|
||||
//bot_npc_type->mount_color = 0;
|
||||
//bot_npc_type->attack_speed = 0.0f;
|
||||
//bot_npc_type->attack_delay = 0;
|
||||
//bot_npc_type->accuracy_rating = 0;
|
||||
//bot_npc_type->avoidance_rating = 0;
|
||||
//bot_npc_type->findable = false;
|
||||
bot_npc_type->trackable = true;
|
||||
//bot_npc_type->slow_mitigation = 0;
|
||||
bot_npc_type->maxlevel = botLevel;
|
||||
//bot_npc_type->scalerate = 0;
|
||||
//bot_npc_type->private_corpse = false;
|
||||
//bot_npc_type->unique_spawn_by_name = false;
|
||||
//bot_npc_type->underwater = false;
|
||||
//bot_npc_type->emoteid = 0;
|
||||
//bot_npc_type->spellscale = 0.0f;
|
||||
//bot_npc_type->healscale = 0.0f;
|
||||
//bot_npc_type->no_target_hotkey = false;
|
||||
//bot_npc_type->raid_target = false;
|
||||
//bot_npc_type->armtexture = 0;
|
||||
//bot_npc_type->bracertexture = 0;
|
||||
//bot_npc_type->handtexture = 0;
|
||||
//bot_npc_type->legtexture = 0;
|
||||
//bot_npc_type->feettexture = 0;
|
||||
//bot_npc_type->ignore_despawn = false;
|
||||
bot_npc_type->show_name = true;
|
||||
//bot_npc_type->untargetable = false;
|
||||
bot_npc_type->skip_global_loot = true;
|
||||
//bot_npc_type->rare_spawn = false;
|
||||
bot_npc_type->stuck_behavior = Ground;
|
||||
|
||||
return bot_npc_type;
|
||||
}
|
||||
|
||||
void Bot::GenerateBaseStats()
|
||||
@@ -1553,25 +1700,25 @@ bool Bot::Save()
|
||||
|
||||
if(!GetBotID()) { // New bot record
|
||||
uint32 bot_id = 0;
|
||||
if (!botdb.SaveNewBot(this, bot_id) || !bot_id) {
|
||||
if (!database.botdb.SaveNewBot(this, bot_id) || !bot_id) {
|
||||
bot_owner->Message(13, "%s '%s'", BotDatabase::fail::SaveNewBot(), GetCleanName());
|
||||
return false;
|
||||
}
|
||||
SetBotID(bot_id);
|
||||
}
|
||||
else { // Update existing bot record
|
||||
if (!botdb.SaveBot(this)) {
|
||||
if (!database.botdb.SaveBot(this)) {
|
||||
bot_owner->Message(13, "%s '%s'", BotDatabase::fail::SaveBot(), GetCleanName());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// All of these continue to process if any fail
|
||||
if (!botdb.SaveBuffs(this))
|
||||
if (!database.botdb.SaveBuffs(this))
|
||||
bot_owner->Message(13, "%s for '%s'", BotDatabase::fail::SaveBuffs(), GetCleanName());
|
||||
if (!botdb.SaveTimers(this))
|
||||
if (!database.botdb.SaveTimers(this))
|
||||
bot_owner->Message(13, "%s for '%s'", BotDatabase::fail::SaveTimers(), GetCleanName());
|
||||
if (!botdb.SaveStance(this))
|
||||
if (!database.botdb.SaveStance(this))
|
||||
bot_owner->Message(13, "%s for '%s'", BotDatabase::fail::SaveStance(), GetCleanName());
|
||||
|
||||
if (!SavePet())
|
||||
@@ -1586,20 +1733,20 @@ bool Bot::DeleteBot()
|
||||
if (!bot_owner)
|
||||
return false;
|
||||
|
||||
if (!botdb.DeleteHealRotation(GetBotID())) {
|
||||
if (!database.botdb.DeleteHealRotation(GetBotID())) {
|
||||
bot_owner->Message(13, "%s", BotDatabase::fail::DeleteHealRotation());
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string query = StringFormat("DELETE FROM `bot_heal_rotation_members` WHERE `bot_id` = '%u'", GetBotID());
|
||||
auto results = botdb.QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
bot_owner->Message(13, "Failed to delete heal rotation member '%s'", GetCleanName());
|
||||
return false;
|
||||
}
|
||||
|
||||
query = StringFormat("DELETE FROM `bot_heal_rotation_targets` WHERE `target_name` LIKE '%s'", GetCleanName());
|
||||
results = botdb.QueryDatabase(query);
|
||||
results = database.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
bot_owner->Message(13, "Failed to delete heal rotation target '%s'", GetCleanName());
|
||||
return false;
|
||||
@@ -1615,32 +1762,32 @@ bool Bot::DeleteBot()
|
||||
|
||||
std::string error_message;
|
||||
|
||||
if (!botdb.RemoveMemberFromBotGroup(GetBotID())) {
|
||||
if (!database.botdb.RemoveMemberFromBotGroup(GetBotID())) {
|
||||
bot_owner->Message(13, "%s - '%s'", BotDatabase::fail::RemoveMemberFromBotGroup(), GetCleanName());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!botdb.DeleteItems(GetBotID())) {
|
||||
if (!database.botdb.DeleteItems(GetBotID())) {
|
||||
bot_owner->Message(13, "%s for '%s'", BotDatabase::fail::DeleteItems(), GetCleanName());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!botdb.DeleteTimers(GetBotID())) {
|
||||
if (!database.botdb.DeleteTimers(GetBotID())) {
|
||||
bot_owner->Message(13, "%s for '%s'", BotDatabase::fail::DeleteTimers(), GetCleanName());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!botdb.DeleteBuffs(GetBotID())) {
|
||||
if (!database.botdb.DeleteBuffs(GetBotID())) {
|
||||
bot_owner->Message(13, "%s for '%s'", BotDatabase::fail::DeleteBuffs(), GetCleanName());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!botdb.DeleteStance(GetBotID())) {
|
||||
if (!database.botdb.DeleteStance(GetBotID())) {
|
||||
bot_owner->Message(13, "%s for '%s'", BotDatabase::fail::DeleteStance(), GetCleanName());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!botdb.DeleteBot(GetBotID())) {
|
||||
if (!database.botdb.DeleteBot(GetBotID())) {
|
||||
bot_owner->Message(13, "%s '%s'", BotDatabase::fail::DeleteBot(), GetCleanName());
|
||||
return false;
|
||||
}
|
||||
@@ -1684,7 +1831,7 @@ bool Bot::LoadPet()
|
||||
std::string error_message;
|
||||
|
||||
uint32 pet_index = 0;
|
||||
if (!botdb.LoadPetIndex(GetBotID(), pet_index)) {
|
||||
if (!database.botdb.LoadPetIndex(GetBotID(), pet_index)) {
|
||||
bot_owner->Message(13, "%s for %s's pet", BotDatabase::fail::LoadPetIndex(), GetCleanName());
|
||||
return false;
|
||||
}
|
||||
@@ -1692,7 +1839,7 @@ bool Bot::LoadPet()
|
||||
return true;
|
||||
|
||||
uint32 saved_pet_spell_id = 0;
|
||||
if (!botdb.LoadPetSpellID(GetBotID(), saved_pet_spell_id)) {
|
||||
if (!database.botdb.LoadPetSpellID(GetBotID(), saved_pet_spell_id)) {
|
||||
bot_owner->Message(13, "%s for %s's pet", BotDatabase::fail::LoadPetSpellID(), GetCleanName());
|
||||
}
|
||||
if (!IsValidSpell(saved_pet_spell_id)) {
|
||||
@@ -1706,7 +1853,7 @@ bool Bot::LoadPet()
|
||||
uint32 pet_hp = 0;
|
||||
uint32 pet_spell_id = 0;
|
||||
|
||||
if (!botdb.LoadPetStats(GetBotID(), pet_name, pet_mana, pet_hp, pet_spell_id)) {
|
||||
if (!database.botdb.LoadPetStats(GetBotID(), pet_name, pet_mana, pet_hp, pet_spell_id)) {
|
||||
bot_owner->Message(13, "%s for %s's pet", BotDatabase::fail::LoadPetStats(), GetCleanName());
|
||||
return false;
|
||||
}
|
||||
@@ -1721,12 +1868,12 @@ bool Bot::LoadPet()
|
||||
|
||||
SpellBuff_Struct pet_buffs[PET_BUFF_COUNT];
|
||||
memset(pet_buffs, 0, (sizeof(SpellBuff_Struct) * PET_BUFF_COUNT));
|
||||
if (!botdb.LoadPetBuffs(GetBotID(), pet_buffs))
|
||||
if (!database.botdb.LoadPetBuffs(GetBotID(), pet_buffs))
|
||||
bot_owner->Message(13, "%s for %s's pet", BotDatabase::fail::LoadPetBuffs(), GetCleanName());
|
||||
|
||||
uint32 pet_items[EQEmu::invslot::EQUIPMENT_COUNT];
|
||||
memset(pet_items, 0, (sizeof(uint32) * EQEmu::invslot::EQUIPMENT_COUNT));
|
||||
if (!botdb.LoadPetItems(GetBotID(), pet_items))
|
||||
if (!database.botdb.LoadPetItems(GetBotID(), pet_items))
|
||||
bot_owner->Message(13, "%s for %s's pet", BotDatabase::fail::LoadPetItems(), GetCleanName());
|
||||
|
||||
pet_inst->SetPetState(pet_buffs, pet_items);
|
||||
@@ -1765,14 +1912,14 @@ bool Bot::SavePet()
|
||||
|
||||
std::string error_message;
|
||||
|
||||
if (!botdb.SavePetStats(GetBotID(), pet_name_str, pet_inst->GetMana(), pet_inst->GetHP(), pet_inst->GetPetSpellID())) {
|
||||
if (!database.botdb.SavePetStats(GetBotID(), pet_name_str, pet_inst->GetMana(), pet_inst->GetHP(), pet_inst->GetPetSpellID())) {
|
||||
bot_owner->Message(13, "%s for %s's pet", BotDatabase::fail::SavePetStats(), GetCleanName());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!botdb.SavePetBuffs(GetBotID(), pet_buffs))
|
||||
if (!database.botdb.SavePetBuffs(GetBotID(), pet_buffs))
|
||||
bot_owner->Message(13, "%s for %s's pet", BotDatabase::fail::SavePetBuffs(), GetCleanName());
|
||||
if (!botdb.SavePetItems(GetBotID(), pet_items))
|
||||
if (!database.botdb.SavePetItems(GetBotID(), pet_items))
|
||||
bot_owner->Message(13, "%s for %s's pet", BotDatabase::fail::SavePetItems(), GetCleanName());
|
||||
|
||||
return true;
|
||||
@@ -1786,15 +1933,15 @@ bool Bot::DeletePet()
|
||||
|
||||
std::string error_message;
|
||||
|
||||
if (!botdb.DeletePetItems(GetBotID())) {
|
||||
if (!database.botdb.DeletePetItems(GetBotID())) {
|
||||
bot_owner->Message(13, "%s for %s's pet", BotDatabase::fail::DeletePetItems(), GetCleanName());
|
||||
return false;
|
||||
}
|
||||
if (!botdb.DeletePetBuffs(GetBotID())) {
|
||||
if (!database.botdb.DeletePetBuffs(GetBotID())) {
|
||||
bot_owner->Message(13, "%s for %s's pet", BotDatabase::fail::DeletePetBuffs(), GetCleanName());
|
||||
return false;
|
||||
}
|
||||
if (!botdb.DeletePetStats(GetBotID())) {
|
||||
if (!database.botdb.DeletePetStats(GetBotID())) {
|
||||
bot_owner->Message(13, "%s for %s's pet", BotDatabase::fail::DeletePetStats(), GetCleanName());
|
||||
return false;
|
||||
}
|
||||
@@ -1867,6 +2014,17 @@ bool Bot::Process() {
|
||||
if(GetAppearance() == eaDead && GetHP() > 0)
|
||||
SetAppearance(eaStanding);
|
||||
|
||||
if (IsMoving()) {
|
||||
ping_timer.Disable();
|
||||
}
|
||||
else {
|
||||
if (!ping_timer.Enabled())
|
||||
ping_timer.Start(BOT_KEEP_ALIVE_INTERVAL);
|
||||
|
||||
if (ping_timer.Check())
|
||||
SentPositionPacket(0.0f, 0.0f, 0.0f, 0.0f, 0);
|
||||
}
|
||||
|
||||
if (IsStunned() || IsMezzed())
|
||||
return true;
|
||||
|
||||
@@ -2091,10 +2249,9 @@ void Bot::AI_Process() {
|
||||
|
||||
Client* bot_owner = (GetBotOwner() && GetBotOwner()->IsClient() ? GetBotOwner()->CastToClient() : nullptr);
|
||||
Group* bot_group = GetGroup();
|
||||
Mob* follow_mob = entity_list.GetMob(GetFollowID());
|
||||
|
||||
|
||||
// Primary reasons for not processing AI
|
||||
if (!bot_owner || !bot_group || !follow_mob || !IsAIControlled())
|
||||
if (!bot_owner || !bot_group || !IsAIControlled())
|
||||
return;
|
||||
|
||||
if (bot_owner->IsDead()) {
|
||||
@@ -2104,11 +2261,18 @@ void Bot::AI_Process() {
|
||||
return;
|
||||
}
|
||||
|
||||
// We also need a leash owner (subset of primary AI criteria)
|
||||
// We also need a leash owner and follow mob (subset of primary AI criteria)
|
||||
Client* leash_owner = (bot_group->GetLeader() && bot_group->GetLeader()->IsClient() ? bot_group->GetLeader()->CastToClient() : bot_owner);
|
||||
if (!leash_owner)
|
||||
return;
|
||||
|
||||
Mob* follow_mob = entity_list.GetMob(GetFollowID());
|
||||
|
||||
if (!follow_mob) {
|
||||
follow_mob = leash_owner;
|
||||
SetFollowID(leash_owner->GetID());
|
||||
}
|
||||
|
||||
// Berserk updates should occur if primary AI criteria are met
|
||||
if (GetClass() == WARRIOR || GetClass() == BERSERKER) {
|
||||
if (!berserk && GetHP() > 0 && GetHPRatio() < 30.0f) {
|
||||
@@ -2603,7 +2767,7 @@ void Bot::AI_Process() {
|
||||
// we can't fight if we don't have a target, are stun/mezzed or dead..
|
||||
// Stop attacking if the target is enraged
|
||||
TEST_TARGET();
|
||||
if (GetBotStance() == BotStancePassive || (tar->IsEnraged() && !BehindMob(tar, GetX(), GetY())))
|
||||
if (GetBotStance() == EQEmu::constants::stancePassive || (tar->IsEnraged() && !BehindMob(tar, GetX(), GetY())))
|
||||
return;
|
||||
|
||||
// First, special attack per class (kick, backstab etc..)
|
||||
@@ -2730,7 +2894,7 @@ void Bot::AI_Process() {
|
||||
FaceTarget(GetTarget());
|
||||
|
||||
// This is a mob that is fleeing either because it has been feared or is low on hitpoints
|
||||
if (GetBotStance() != BotStancePassive) {
|
||||
if (GetBotStance() != EQEmu::constants::stancePassive) {
|
||||
AI_PursueCastCheck(); // This appears to always return true..can't trust for success/fail
|
||||
return;
|
||||
}
|
||||
@@ -2738,7 +2902,7 @@ void Bot::AI_Process() {
|
||||
} // end not in combat range
|
||||
|
||||
if (!IsMoving() && !spellend_timer.Enabled()) { // This may actually need work...
|
||||
if (GetBotStance() == BotStancePassive)
|
||||
if (GetBotStance() == EQEmu::constants::stancePassive)
|
||||
return;
|
||||
|
||||
if (GetTarget() && AI_EngagedCastCheck())
|
||||
@@ -2796,7 +2960,7 @@ void Bot::AI_Process() {
|
||||
// Ok to idle
|
||||
if (fm_dist <= GetFollowDistance()) {
|
||||
if (!IsMoving() && AI_think_timer->Check() && !spellend_timer.Enabled()) {
|
||||
if (GetBotStance() != BotStancePassive) {
|
||||
if (GetBotStance() != EQEmu::constants::stancePassive) {
|
||||
if (!AI_IdleCastCheck() && !IsCasting() && GetClass() != BARD)
|
||||
BotMeditate(true);
|
||||
}
|
||||
@@ -2841,7 +3005,7 @@ void Bot::AI_Process() {
|
||||
|
||||
// Basically, bard bots get a chance to cast idle spells while moving
|
||||
if (IsMoving()) {
|
||||
if (GetBotStance() != BotStancePassive) {
|
||||
if (GetBotStance() != EQEmu::constants::stancePassive) {
|
||||
if (GetClass() == BARD && !spellend_timer.Enabled() && AI_think_timer->Check()) {
|
||||
AI_IdleCastCheck();
|
||||
return;
|
||||
@@ -3111,6 +3275,7 @@ bool Bot::Spawn(Client* botCharacterOwner) {
|
||||
// Load pet
|
||||
LoadPet();
|
||||
SentPositionPacket(0.0f, 0.0f, 0.0f, 0.0f, 0);
|
||||
ping_timer.Start(8000);
|
||||
// there is something askew with spawn struct appearance fields...
|
||||
// I re-enabled this until I can sort it out
|
||||
uint32 itemID = 0;
|
||||
@@ -3136,7 +3301,7 @@ void Bot::RemoveBotItemBySlot(uint32 slotID, std::string *errorMessage)
|
||||
if(!GetBotID())
|
||||
return;
|
||||
|
||||
if(!botdb.DeleteItemBySlot(GetBotID(), slotID))
|
||||
if(!database.botdb.DeleteItemBySlot(GetBotID(), slotID))
|
||||
*errorMessage = BotDatabase::fail::DeleteItemBySlot();
|
||||
|
||||
m_inv.DeleteItem(slotID);
|
||||
@@ -3149,7 +3314,7 @@ void Bot::GetBotItems(EQEmu::InventoryProfile &inv, std::string* errorMessage)
|
||||
if(!GetBotID())
|
||||
return;
|
||||
|
||||
if (!botdb.LoadItems(GetBotID(), inv)) {
|
||||
if (!database.botdb.LoadItems(GetBotID(), inv)) {
|
||||
*errorMessage = BotDatabase::fail::LoadItems();
|
||||
return;
|
||||
}
|
||||
@@ -3164,7 +3329,7 @@ uint32 Bot::GetBotItemBySlot(uint32 slotID)
|
||||
if(!GetBotID())
|
||||
return item_id;
|
||||
|
||||
if (!botdb.LoadItemBySlot(GetBotID(), slotID, item_id)) {
|
||||
if (!database.botdb.LoadItemBySlot(GetBotID(), slotID, item_id)) {
|
||||
if (GetBotOwner() && GetBotOwner()->IsClient())
|
||||
GetBotOwner()->CastToClient()->Message(13, "%s", BotDatabase::fail::LoadItemBySlot());
|
||||
}
|
||||
@@ -3253,7 +3418,7 @@ Bot* Bot::LoadBot(uint32 botID)
|
||||
if (!botID)
|
||||
return loaded_bot;
|
||||
|
||||
if (!botdb.LoadBot(botID, loaded_bot)) // TODO: Consider update to message handler
|
||||
if (!database.botdb.LoadBot(botID, loaded_bot)) // TODO: Consider update to message handler
|
||||
return loaded_bot;
|
||||
|
||||
return loaded_bot;
|
||||
@@ -3268,7 +3433,7 @@ void Bot::LoadAndSpawnAllZonedBots(Client* botOwner) {
|
||||
uint32 TempGroupId = g->GetID();
|
||||
std::list<uint32> ActiveBots;
|
||||
// Modified LoadGroupedBotsByGroupID to require a CharacterID
|
||||
if (!botdb.LoadGroupedBotsByGroupID(botOwner->CharacterID(), TempGroupId, ActiveBots)) {
|
||||
if (!database.botdb.LoadGroupedBotsByGroupID(botOwner->CharacterID(), TempGroupId, ActiveBots)) {
|
||||
botOwner->Message(13, "%s", BotDatabase::fail::LoadGroupedBotsByGroupID());
|
||||
return;
|
||||
}
|
||||
@@ -3334,7 +3499,7 @@ void Bot::LevelBotWithClient(Client* client, uint8 level, bool sendlvlapp) {
|
||||
Bot* bot = *biter;
|
||||
if(bot && (bot->GetLevel() != client->GetLevel())) {
|
||||
bot->SetPetChooser(false); // not sure what this does, but was in bot 'update' code
|
||||
bot->CalcBotStats(false); // TODO: look at this and see if 'true' should be passed...
|
||||
bot->CalcBotStats(client->GetBotOptionStatsUpdate());
|
||||
if(sendlvlapp)
|
||||
bot->SendLevelAppearance();
|
||||
// modified from Client::SetLevel()
|
||||
@@ -3549,7 +3714,7 @@ void Bot::BotTradeSwapItem(Client* client, int16 lootSlot, const EQEmu::ItemInst
|
||||
void Bot::BotTradeAddItem(uint32 id, const EQEmu::ItemInstance* inst, int16 charges, uint32 equipableSlots, uint16 lootSlot, std::string* errorMessage, bool addToDb)
|
||||
{
|
||||
if(addToDb) {
|
||||
if (!botdb.SaveItemBySlot(this, lootSlot, inst)) {
|
||||
if (!database.botdb.SaveItemBySlot(this, lootSlot, inst)) {
|
||||
*errorMessage = BotDatabase::fail::SaveItemBySlot();
|
||||
return;
|
||||
}
|
||||
@@ -3964,7 +4129,7 @@ void Bot::PerformTradeWithClient(int16 beginSlotID, int16 endSlotID, Client* cli
|
||||
// // TODO: add logging
|
||||
//}
|
||||
|
||||
if (!botdb.DeleteItemBySlot(GetBotID(), return_iterator.fromBotSlot))
|
||||
if (!database.botdb.DeleteItemBySlot(GetBotID(), return_iterator.fromBotSlot))
|
||||
client->Message(CC_Red, "%s (slot: %i, name: '%s')", BotDatabase::fail::DeleteItemBySlot(), return_iterator.fromBotSlot, (return_instance ? return_instance->GetItem()->Name : "nullptr"));
|
||||
|
||||
BotRemoveEquipItem(return_iterator.fromBotSlot);
|
||||
@@ -3979,7 +4144,7 @@ void Bot::PerformTradeWithClient(int16 beginSlotID, int16 endSlotID, Client* cli
|
||||
for (auto& trade_iterator : client_trade) {
|
||||
// TODO: code for stackables
|
||||
|
||||
if (!botdb.SaveItemBySlot(this, trade_iterator.toBotSlot, trade_iterator.tradeItemInstance))
|
||||
if (!database.botdb.SaveItemBySlot(this, trade_iterator.toBotSlot, trade_iterator.tradeItemInstance))
|
||||
client->Message(CC_Red, "%s (slot: %i, name: '%s')", BotDatabase::fail::SaveItemBySlot(), trade_iterator.toBotSlot, (trade_iterator.tradeItemInstance ? trade_iterator.tradeItemInstance->GetItem()->Name : "nullptr"));
|
||||
|
||||
m_inv.PutItem(trade_iterator.toBotSlot, *trade_iterator.tradeItemInstance);
|
||||
@@ -4011,6 +4176,9 @@ void Bot::PerformTradeWithClient(int16 beginSlotID, int16 endSlotID, Client* cli
|
||||
size_t returned_count = client_return.size();
|
||||
|
||||
client->Message(CC_Lime, "Trade with '%s' resulted in %i accepted item%s, %i returned item%s.", GetCleanName(), accepted_count, ((accepted_count == 1) ? "" : "s"), returned_count, ((returned_count == 1) ? "" : "s"));
|
||||
|
||||
if (accepted_count)
|
||||
CalcBotStats(client->GetBotOptionStatsUpdate());
|
||||
}
|
||||
|
||||
bool Bot::Death(Mob *killerMob, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill) {
|
||||
@@ -5776,7 +5944,7 @@ void Bot::ProcessGuildInvite(Client* guildOfficer, Bot* botToGuild) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!botdb.SaveGuildMembership(botToGuild->GetBotID(), guildOfficer->GuildID(), GUILD_MEMBER)) {
|
||||
if (!database.botdb.SaveGuildMembership(botToGuild->GetBotID(), guildOfficer->GuildID(), GUILD_MEMBER)) {
|
||||
guildOfficer->Message(13, "%s for '%s'", BotDatabase::fail::SaveGuildMembership(), botToGuild->GetCleanName());
|
||||
return;
|
||||
}
|
||||
@@ -5801,16 +5969,16 @@ bool Bot::ProcessGuildRemoval(Client* guildOfficer, std::string botName) {
|
||||
if(guildOfficer && !botName.empty()) {
|
||||
Bot* botToUnGuild = entity_list.GetBotByBotName(botName);
|
||||
if(botToUnGuild) {
|
||||
if (botdb.SaveGuildMembership(botToUnGuild->GetBotID(), 0, 0))
|
||||
if (database.botdb.SaveGuildMembership(botToUnGuild->GetBotID(), 0, 0))
|
||||
Result = true;
|
||||
} else {
|
||||
uint32 ownerId = 0;
|
||||
if (!botdb.LoadOwnerID(botName, ownerId))
|
||||
if (!database.botdb.LoadOwnerID(botName, ownerId))
|
||||
guildOfficer->Message(13, "%s for '%s'", BotDatabase::fail::LoadOwnerID(), botName.c_str());
|
||||
uint32 botId = 0;
|
||||
if (!botdb.LoadBotID(ownerId, botName, botId))
|
||||
if (!database.botdb.LoadBotID(ownerId, botName, botId))
|
||||
guildOfficer->Message(13, "%s for '%s'", BotDatabase::fail::LoadBotID(), botName.c_str());
|
||||
if (botId && botdb.SaveGuildMembership(botId, 0, 0))
|
||||
if (botId && database.botdb.SaveGuildMembership(botId, 0, 0))
|
||||
Result = true;
|
||||
}
|
||||
|
||||
@@ -8049,7 +8217,7 @@ bool Bot::CheckLoreConflict(const EQEmu::ItemData* item) {
|
||||
}
|
||||
|
||||
bool EntityList::Bot_AICheckCloseBeneficialSpells(Bot* caster, uint8 iChance, float iRange, uint32 iSpellTypes) {
|
||||
if((iSpellTypes&SpellTypes_Detrimental) != 0) {
|
||||
if((iSpellTypes & SPELL_TYPES_DETRIMENTAL) != 0) {
|
||||
Log(Logs::General, Logs::Error, "Error: detrimental spells requested from AICheckCloseBeneficialSpells!!");
|
||||
return false;
|
||||
}
|
||||
@@ -8104,19 +8272,19 @@ bool EntityList::Bot_AICheckCloseBeneficialSpells(Bot* caster, uint8 iChance, fl
|
||||
Group *g = caster->GetGroup();
|
||||
float hpRatioToHeal = 25.0f;
|
||||
switch(caster->GetBotStance()) {
|
||||
case BotStanceReactive:
|
||||
case BotStanceBalanced:
|
||||
hpRatioToHeal = 50.0f;
|
||||
break;
|
||||
case BotStanceBurn:
|
||||
case BotStanceBurnAE:
|
||||
hpRatioToHeal = 20.0f;
|
||||
break;
|
||||
case BotStanceAggressive:
|
||||
case BotStanceEfficient:
|
||||
default:
|
||||
hpRatioToHeal = 25.0f;
|
||||
break;
|
||||
case EQEmu::constants::stanceReactive:
|
||||
case EQEmu::constants::stanceBalanced:
|
||||
hpRatioToHeal = 50.0f;
|
||||
break;
|
||||
case EQEmu::constants::stanceBurn:
|
||||
case EQEmu::constants::stanceBurnAE:
|
||||
hpRatioToHeal = 20.0f;
|
||||
break;
|
||||
case EQEmu::constants::stanceAggressive:
|
||||
case EQEmu::constants::stanceEfficient:
|
||||
default:
|
||||
hpRatioToHeal = 25.0f;
|
||||
break;
|
||||
}
|
||||
|
||||
if(g) {
|
||||
@@ -8655,11 +8823,11 @@ bool Bot::HasOrMayGetAggro() {
|
||||
}
|
||||
|
||||
void Bot::SetDefaultBotStance() {
|
||||
BotStanceType defaultStance = BotStanceBalanced;
|
||||
EQEmu::constants::StanceType defaultStance = EQEmu::constants::stanceBalanced;
|
||||
if (GetClass() == WARRIOR)
|
||||
defaultStance = BotStanceAggressive;
|
||||
defaultStance = EQEmu::constants::stanceAggressive;
|
||||
|
||||
_baseBotStance = BotStancePassive;
|
||||
_baseBotStance = EQEmu::constants::stancePassive;
|
||||
_botStance = defaultStance;
|
||||
}
|
||||
|
||||
@@ -8900,7 +9068,7 @@ bool Bot::DyeArmor(int16 slot_id, uint32 rgb, bool all_flag, bool save_flag)
|
||||
if (all_flag)
|
||||
save_slot = -2;
|
||||
|
||||
if (!botdb.SaveEquipmentColor(GetBotID(), save_slot, rgb)) {
|
||||
if (!database.botdb.SaveEquipmentColor(GetBotID(), save_slot, rgb)) {
|
||||
if (GetBotOwner() && GetBotOwner()->IsClient())
|
||||
GetBotOwner()->CastToClient()->Message(13, "%s", BotDatabase::fail::SaveEquipmentColor());
|
||||
return false;
|
||||
@@ -8932,4 +9100,6 @@ std::string Bot::CreateSayLink(Client* c, const char* message, const char* name)
|
||||
return saylink;
|
||||
}
|
||||
|
||||
uint8 Bot::spell_casting_chances[SPELL_TYPE_COUNT][PLAYER_CLASS_COUNT][EQEmu::constants::STANCE_TYPE_COUNT][cntHSND] = { 0 };
|
||||
|
||||
#endif
|
||||
|
||||
+50
-117
@@ -29,7 +29,6 @@
|
||||
#include "groups.h"
|
||||
#include "corpse.h"
|
||||
#include "zonedb.h"
|
||||
#include "bot_database.h"
|
||||
#include "string_ids.h"
|
||||
#include "../common/misc_functions.h"
|
||||
#include "../common/global_define.h"
|
||||
@@ -44,6 +43,8 @@
|
||||
|
||||
#define BOT_LEASH_DISTANCE 250000 // as DSq value (500 units)
|
||||
|
||||
#define BOT_KEEP_ALIVE_INTERVAL 5000 // 5 seconds
|
||||
|
||||
extern WorldServer worldserver;
|
||||
|
||||
const int BotAISpellRange = 100; // TODO: Write a method that calcs what the bot's spell range is based on spell, equipment, AA, whatever and replace this
|
||||
@@ -52,91 +53,7 @@ const int MaxDisciplineTimer = 10;
|
||||
const int DisciplineReuseStart = MaxSpellTimer + 1;
|
||||
const int MaxTimer = MaxSpellTimer + MaxDisciplineTimer;
|
||||
|
||||
enum BotStanceType {
|
||||
BotStancePassive,
|
||||
BotStanceBalanced,
|
||||
BotStanceEfficient,
|
||||
BotStanceReactive,
|
||||
BotStanceAggressive,
|
||||
BotStanceBurn,
|
||||
BotStanceBurnAE,
|
||||
BotStanceUnknown,
|
||||
MaxStances = BotStanceUnknown
|
||||
};
|
||||
|
||||
#define BOT_STANCE_COUNT 8
|
||||
#define VALIDBOTSTANCE(x) ((x >= (int)BotStancePassive && x <= (int)BotStanceBurnAE) ? ((BotStanceType)x) : (BotStanceUnknown))
|
||||
|
||||
static const std::string bot_stance_name[BOT_STANCE_COUNT] = {
|
||||
"Passive", // 0
|
||||
"Balanced", // 1
|
||||
"Efficient", // 2
|
||||
"Reactive", // 3
|
||||
"Aggressive", // 4
|
||||
"Burn", // 5
|
||||
"BurnAE", // 6
|
||||
"Unknown" // 7
|
||||
};
|
||||
|
||||
static const char* GetBotStanceName(int stance_id) { return bot_stance_name[VALIDBOTSTANCE(stance_id)].c_str(); }
|
||||
|
||||
#define VALIDBOTEQUIPSLOT(x) ((x >= EQEmu::invslot::EQUIPMENT_BEGIN && x <= EQEmu::invslot::EQUIPMENT_END) ? (x) : (EQEmu::invslot::EQUIPMENT_COUNT))
|
||||
|
||||
static const std::string bot_equip_slot_name[EQEmu::invslot::EQUIPMENT_COUNT + 1] =
|
||||
{
|
||||
"Charm", // slotCharm
|
||||
"Ear 1", // slotEar1
|
||||
"Head", // slotHead
|
||||
"Face", // slotFace
|
||||
"Ear 2", // slotEar2
|
||||
"Neck", // slotNeck
|
||||
"Shoulders", // slotShoulders
|
||||
"Arms", // slotArms
|
||||
"Back", // slotBack
|
||||
"Wrist 1", // slotWrist1
|
||||
"Wrist 2", // slotWrist2
|
||||
"Range", // slotRange
|
||||
"Hands", // slotHands
|
||||
"Primary", // slotPrimary
|
||||
"Secondary", // slotSecondary
|
||||
"Finger 1", // slotFinger1
|
||||
"Finger 2", // slotFinger2
|
||||
"Chest", // slotChest
|
||||
"Legs", // slotLegs
|
||||
"Feet", // slotFeet
|
||||
"Waist", // slotWaist
|
||||
"Power Source", // slotPowerSource
|
||||
"Ammo", // slotAmmo
|
||||
"Unknown"
|
||||
};
|
||||
|
||||
static const char* GetBotEquipSlotName(int slot_id) { return bot_equip_slot_name[VALIDBOTEQUIPSLOT(slot_id)].c_str(); }
|
||||
|
||||
enum SpellTypeIndex {
|
||||
SpellType_NukeIndex,
|
||||
SpellType_HealIndex,
|
||||
SpellType_RootIndex,
|
||||
SpellType_BuffIndex,
|
||||
SpellType_EscapeIndex,
|
||||
SpellType_PetIndex,
|
||||
SpellType_LifetapIndex,
|
||||
SpellType_SnareIndex,
|
||||
SpellType_DOTIndex,
|
||||
SpellType_DispelIndex,
|
||||
SpellType_InCombatBuffIndex,
|
||||
SpellType_MezIndex,
|
||||
SpellType_CharmIndex,
|
||||
SpellType_SlowIndex,
|
||||
SpellType_DebuffIndex,
|
||||
SpellType_CureIndex,
|
||||
SpellType_ResurrectIndex,
|
||||
SpellType_HateReduxIndex,
|
||||
SpellType_InCombatBuffSongIndex,
|
||||
SpellType_OutOfCombatBuffSongIndex,
|
||||
SpellType_PreCombatBuffIndex,
|
||||
SpellType_PreCombatBuffSongIndex,
|
||||
MaxSpellTypes
|
||||
};
|
||||
|
||||
// nHSND negative Healer/Slower/Nuker/Doter
|
||||
// pH positive Healer
|
||||
@@ -226,32 +143,38 @@ public:
|
||||
BotRoleRaidHealer
|
||||
};
|
||||
|
||||
enum EqExpansions { // expansions are off..EQ should be '0'
|
||||
ExpansionNone,
|
||||
ExpansionEQ,
|
||||
ExpansionRoK,
|
||||
ExpansionSoV,
|
||||
ExpansionSoL,
|
||||
ExpansionPoP,
|
||||
ExpansionLoY,
|
||||
ExpansionLDoN,
|
||||
ExpansionGoD,
|
||||
ExpansionOoW,
|
||||
ExpansionDoN,
|
||||
ExpansionDoDH,
|
||||
ExpansionPoR,
|
||||
ExpansionTSS,
|
||||
ExpansionSoF,
|
||||
ExpansionSoD,
|
||||
ExpansionUF,
|
||||
ExpansionHoT,
|
||||
ExpansionVoA,
|
||||
ExpansionRoF
|
||||
enum SpellTypeIndex : uint32 {
|
||||
spellTypeIndexNuke,
|
||||
spellTypeIndexHeal,
|
||||
spellTypeIndexRoot,
|
||||
spellTypeIndexBuff,
|
||||
spellTypeIndexEscape,
|
||||
spellTypeIndexPet,
|
||||
spellTypeIndexLifetap,
|
||||
spellTypeIndexSnare,
|
||||
spellTypeIndexDot,
|
||||
spellTypeIndexDispel,
|
||||
spellTypeIndexInCombatBuff,
|
||||
spellTypeIndexMez,
|
||||
spellTypeIndexCharm,
|
||||
spellTypeIndexSlow,
|
||||
spellTypeIndexDebuff,
|
||||
spellTypeIndexCure,
|
||||
spellTypeIndexResurrect,
|
||||
spellTypeIndexHateRedux,
|
||||
spellTypeIndexInCombatBuffSong,
|
||||
spellTypeIndexOutOfCombatBuffSong,
|
||||
spellTypeIndexPreCombatBuff,
|
||||
spellTypeIndexPreCombatBuffSong
|
||||
};
|
||||
|
||||
static const uint32 SPELL_TYPE_FIRST = spellTypeIndexNuke;
|
||||
static const uint32 SPELL_TYPE_LAST = spellTypeIndexPreCombatBuffSong;
|
||||
static const uint32 SPELL_TYPE_COUNT = SPELL_TYPE_LAST + 1;
|
||||
|
||||
// Class Constructors
|
||||
Bot(NPCType npcTypeData, Client* botOwner);
|
||||
Bot(uint32 botID, uint32 botOwnerCharacterID, uint32 botSpellsID, double totalPlayTime, uint32 lastZoneId, NPCType npcTypeData);
|
||||
Bot(NPCType *npcTypeData, Client* botOwner);
|
||||
Bot(uint32 botID, uint32 botOwnerCharacterID, uint32 botSpellsID, double totalPlayTime, uint32 lastZoneId, NPCType *npcTypeData);
|
||||
|
||||
//abstract virtual function implementations requird by base abstract class
|
||||
virtual bool Death(Mob* killerMob, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill);
|
||||
@@ -337,9 +260,10 @@ public:
|
||||
void Stand();
|
||||
bool IsSitting();
|
||||
bool IsStanding();
|
||||
int GetBotWalkspeed() const { return (int)((float)_GetWalkSpeed() * 1.786f); } // 1.25 / 0.7 = 1.7857142857142857142857142857143
|
||||
int GetBotRunspeed() const { return (int)((float)_GetRunSpeed() * 1.786f); }
|
||||
int GetBotFearSpeed() const { return (int)((float)_GetFearSpeed() * 1.786f); }
|
||||
virtual int GetWalkspeed() const { return (int)((float)_GetWalkSpeed() * 1.785714f); } // 1.25 / 0.7 = 1.7857142857142857142857142857143
|
||||
virtual int GetRunspeed() const { return (int)((float)_GetRunSpeed() * 1.785714f); }
|
||||
virtual void WalkTo(float x, float y, float z);
|
||||
virtual void RunTo(float x, float y, float z);
|
||||
bool UseDiscipline(uint32 spell_id, uint32 target);
|
||||
uint8 GetNumberNeedingHealedInGroup(uint8 hpr, bool includePets);
|
||||
bool GetNeedsCured(Mob *tar);
|
||||
@@ -494,7 +418,7 @@ public:
|
||||
static BotSpell GetBestBotSpellForCure(Bot* botCaster, Mob* target);
|
||||
static BotSpell GetBestBotSpellForResistDebuff(Bot* botCaster, Mob* target);
|
||||
|
||||
static NPCType CreateDefaultNPCTypeStructForBot(std::string botName, std::string botLastName, uint8 botLevel, uint16 botRace, uint8 botClass, uint8 gender);
|
||||
static NPCType *CreateDefaultNPCTypeStructForBot(std::string botName, std::string botLastName, uint8 botLevel, uint16 botRace, uint8 botClass, uint8 gender);
|
||||
|
||||
// Static Bot Group Methods
|
||||
static bool AddBotToGroup(Bot* bot, Group* group);
|
||||
@@ -516,7 +440,7 @@ public:
|
||||
virtual bool IsBot() const { return true; }
|
||||
bool GetRangerAutoWeaponSelect() { return _rangerAutoWeaponSelect; }
|
||||
BotRoleType GetBotRole() { return _botRole; }
|
||||
BotStanceType GetBotStance() { return _botStance; }
|
||||
EQEmu::constants::StanceType GetBotStance() { return _botStance; }
|
||||
uint8 GetChanceToCastBySpellType(uint32 spellType);
|
||||
|
||||
bool IsGroupHealer() { return m_CastingRoles.GroupHealer; }
|
||||
@@ -630,7 +554,12 @@ public:
|
||||
// void SetBotOwnerCharacterID(uint32 botOwnerCharacterID) { _botOwnerCharacterID = botOwnerCharacterID; }
|
||||
void SetRangerAutoWeaponSelect(bool enable) { GetClass() == RANGER ? _rangerAutoWeaponSelect = enable : _rangerAutoWeaponSelect = false; }
|
||||
void SetBotRole(BotRoleType botRole) { _botRole = botRole; }
|
||||
void SetBotStance(BotStanceType botStance) { _botStance = ((botStance != BotStanceUnknown) ? (botStance) : (BotStancePassive)); }
|
||||
void SetBotStance(EQEmu::constants::StanceType botStance) {
|
||||
if (botStance >= EQEmu::constants::stancePassive && botStance <= EQEmu::constants::stanceBurnAE)
|
||||
_botStance = botStance;
|
||||
else
|
||||
_botStance = EQEmu::constants::stancePassive;
|
||||
}
|
||||
void SetSpellRecastTimer(int timer_index, int32 recast_delay);
|
||||
void SetDisciplineRecastTimer(int timer_index, int32 recast_delay);
|
||||
void SetAltOutOfCombatBehavior(bool behavior_flag) { _altoutofcombatbehavior = behavior_flag;}
|
||||
@@ -656,7 +585,7 @@ public:
|
||||
virtual void BotRangedAttack(Mob* other);
|
||||
|
||||
// Publicized private functions
|
||||
static NPCType FillNPCTypeStruct(uint32 botSpellsID, std::string botName, std::string botLastName, uint8 botLevel, uint16 botRace, uint8 botClass, uint8 gender, float size, uint32 face, uint32 hairStyle, uint32 hairColor, uint32 eyeColor, uint32 eyeColor2, uint32 beardColor, uint32 beard, uint32 drakkinHeritage, uint32 drakkinTattoo, uint32 drakkinDetails, int32 hp, int32 mana, int32 mr, int32 cr, int32 dr, int32 fr, int32 pr, int32 corrup, int32 ac, uint32 str, uint32 sta, uint32 dex, uint32 agi, uint32 _int, uint32 wis, uint32 cha, uint32 attack);
|
||||
static NPCType *FillNPCTypeStruct(uint32 botSpellsID, std::string botName, std::string botLastName, uint8 botLevel, uint16 botRace, uint8 botClass, uint8 gender, float size, uint32 face, uint32 hairStyle, uint32 hairColor, uint32 eyeColor, uint32 eyeColor2, uint32 beardColor, uint32 beard, uint32 drakkinHeritage, uint32 drakkinTattoo, uint32 drakkinDetails, int32 hp, int32 mana, int32 mr, int32 cr, int32 dr, int32 fr, int32 pr, int32 corrup, int32 ac, uint32 str, uint32 sta, uint32 dex, uint32 agi, uint32 _int, uint32 wis, uint32 cha, uint32 attack);
|
||||
void BotRemoveEquipItem(int16 slot);
|
||||
void RemoveBotItemBySlot(uint32 slotID, std::string* errorMessage);
|
||||
uint32 GetTotalPlayTime();
|
||||
@@ -724,12 +653,13 @@ private:
|
||||
uint32 _lastZoneId;
|
||||
bool _rangerAutoWeaponSelect;
|
||||
BotRoleType _botRole;
|
||||
BotStanceType _botStance;
|
||||
BotStanceType _baseBotStance;
|
||||
EQEmu::constants::StanceType _botStance;
|
||||
EQEmu::constants::StanceType _baseBotStance;
|
||||
unsigned int RestRegenHP;
|
||||
unsigned int RestRegenMana;
|
||||
unsigned int RestRegenEndurance;
|
||||
Timer rest_timer;
|
||||
Timer ping_timer;
|
||||
int32 base_end;
|
||||
int32 cur_end;
|
||||
int32 max_end;
|
||||
@@ -788,6 +718,9 @@ private:
|
||||
bool LoadPet(); // Load and spawn bot pet if there is one
|
||||
bool SavePet(); // Save and depop bot pet if there is one
|
||||
bool DeletePet();
|
||||
|
||||
public:
|
||||
static uint8 spell_casting_chances[SPELL_TYPE_COUNT][PLAYER_CLASS_COUNT][EQEmu::constants::STANCE_TYPE_COUNT][cntHSND];
|
||||
};
|
||||
|
||||
#endif // BOTS
|
||||
|
||||
+138
-86
@@ -59,7 +59,7 @@
|
||||
|
||||
|
||||
#include "bot_command.h"
|
||||
#include "bot_database.h"
|
||||
#include "zonedb.h"
|
||||
#include "guild_mgr.h"
|
||||
#include "map.h"
|
||||
#include "doors.h"
|
||||
@@ -1401,7 +1401,8 @@ int bot_command_init(void)
|
||||
bot_command_add("movementspeed", "Orders a bot to cast a movement speed enhancement spell", 0, bot_command_movement_speed) ||
|
||||
bot_command_add("owneroption", "Sets options available to bot owners", 0, bot_command_owner_option) ||
|
||||
bot_command_add("pet", "Lists the available bot pet [subcommands]", 0, bot_command_pet) ||
|
||||
bot_command_add("petremove", "Orders a bot to remove its pet", 0, bot_subcommand_pet_remove) ||
|
||||
bot_command_add("petgetlost", "Orders a bot to remove its summoned pet", 0, bot_subcommand_pet_get_lost) ||
|
||||
bot_command_add("petremove", "Orders a bot to remove its charmed pet", 0, bot_subcommand_pet_remove) ||
|
||||
bot_command_add("petsettype", "Orders a Magician bot to use a specified pet type", 0, bot_subcommand_pet_set_type) ||
|
||||
bot_command_add("picklock", "Orders a capable bot to pick the lock of the closest door", 0, bot_command_pick_lock) ||
|
||||
bot_command_add("portal", "Orders a Wizard bot to open a magical doorway to a specified destination", 0, bot_subcommand_portal) ||
|
||||
@@ -1422,7 +1423,7 @@ int bot_command_init(void)
|
||||
}
|
||||
|
||||
std::map<std::string, std::pair<uint8, std::vector<std::string>>> bot_command_settings;
|
||||
botdb.LoadBotCommandSettings(bot_command_settings);
|
||||
database.botdb.LoadBotCommandSettings(bot_command_settings);
|
||||
|
||||
auto working_bcl = bot_command_list;
|
||||
for (auto working_bcl_iter : working_bcl) {
|
||||
@@ -1868,11 +1869,11 @@ namespace MyBots
|
||||
std::string group_name = name;
|
||||
|
||||
uint32 botgroup_id = 0;
|
||||
if (!botdb.LoadBotGroupIDForLoadBotGroup(bot_owner->CharacterID(), group_name, botgroup_id) || !botgroup_id)
|
||||
if (!database.botdb.LoadBotGroupIDForLoadBotGroup(bot_owner->CharacterID(), group_name, botgroup_id) || !botgroup_id)
|
||||
return;
|
||||
|
||||
std::map<uint32, std::list<uint32>> botgroup_list;
|
||||
if (!botdb.LoadBotGroup(group_name, botgroup_list) || botgroup_list.find(botgroup_id) == botgroup_list.end() || !botgroup_list[botgroup_id].size())
|
||||
if (!database.botdb.LoadBotGroup(group_name, botgroup_list) || botgroup_list.find(botgroup_id) == botgroup_list.end() || !botgroup_list[botgroup_id].size())
|
||||
return;
|
||||
|
||||
std::list<Bot*> selectable_bot_list;
|
||||
@@ -3441,16 +3442,34 @@ void bot_command_movement_speed(Client *c, const Seperator *sep)
|
||||
void bot_command_owner_option(Client *c, const Seperator *sep)
|
||||
{
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
c->Message(m_usage, "usage: %s [deathmarquee]", sep->arg[0]);
|
||||
c->Message(m_usage, "usage: %s [deathmarquee | statsupdate] (argument: enable | disable | null (toggles))", sep->arg[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
std::string owner_option = sep->arg[1];
|
||||
std::string flag = sep->arg[2];
|
||||
|
||||
if (!owner_option.compare("deathmarquee")) {
|
||||
c->SetBotOptionDeathMarquee(!c->GetBotOptionDeathMarquee());
|
||||
c->Message(m_action, "Bot death marquee is now %s.", (c->GetBotOptionDeathMarquee() == true ? "enabled" : "disabled"));
|
||||
botdb.SaveOwnerOptionDeathMarquee(c->CharacterID(), c->GetBotOptionDeathMarquee());
|
||||
if (!flag.compare("enable"))
|
||||
c->SetBotOptionDeathMarquee(true);
|
||||
else if (!flag.compare("disable"))
|
||||
c->SetBotOptionDeathMarquee(false);
|
||||
else
|
||||
c->SetBotOptionDeathMarquee(!c->GetBotOptionDeathMarquee());
|
||||
|
||||
database.botdb.SaveOwnerOptionDeathMarquee(c->CharacterID(), c->GetBotOptionDeathMarquee());
|
||||
c->Message(m_action, "Bot 'death marquee' is now %s.", (c->GetBotOptionDeathMarquee() == true ? "enabled" : "disabled"));
|
||||
}
|
||||
else if (!owner_option.compare("statsupdate")) {
|
||||
if (!flag.compare("enable"))
|
||||
c->SetBotOptionStatsUpdate(true);
|
||||
else if (!flag.compare("disable"))
|
||||
c->SetBotOptionStatsUpdate(false);
|
||||
else
|
||||
c->SetBotOptionStatsUpdate(!c->GetBotOptionStatsUpdate());
|
||||
|
||||
database.botdb.SaveOwnerOptionStatsUpdate(c->CharacterID(), c->GetBotOptionStatsUpdate());
|
||||
c->Message(m_action, "Bot 'stats update' is now %s.", (c->GetBotOptionStatsUpdate() == true ? "enabled" : "disabled"));
|
||||
}
|
||||
else {
|
||||
c->Message(m_fail, "Owner option '%s' is not recognized.", owner_option.c_str());
|
||||
@@ -3461,12 +3480,13 @@ void bot_command_pet(Client *c, const Seperator *sep)
|
||||
{
|
||||
/* VS2012 code - begin */
|
||||
std::list<const char*> subcommand_list;
|
||||
subcommand_list.push_back("petgetlost");
|
||||
subcommand_list.push_back("petremove");
|
||||
subcommand_list.push_back("petsettype");
|
||||
/* VS2012 code - end */
|
||||
|
||||
/* VS2013 code
|
||||
const std::list<const char*> subcommand_list = { "petremove", "petsettype" };
|
||||
const std::list<const char*> subcommand_list = { "petgetlost", "petremove", "petsettype" };
|
||||
*/
|
||||
|
||||
if (helper_command_alias_fail(c, "bot_command_pet", sep->arg[0], "pet"))
|
||||
@@ -4222,7 +4242,7 @@ void bot_subcommand_bot_clone(Client *c, const Seperator *sep)
|
||||
std::string error_message;
|
||||
|
||||
bool available_flag = false;
|
||||
if (!botdb.QueryNameAvailablity(bot_name, available_flag)) {
|
||||
if (!database.botdb.QueryNameAvailablity(bot_name, available_flag)) {
|
||||
c->Message(m_fail, "%s", BotDatabase::fail::QueryNameAvailablity());
|
||||
return;
|
||||
}
|
||||
@@ -4234,7 +4254,7 @@ void bot_subcommand_bot_clone(Client *c, const Seperator *sep)
|
||||
uint32 max_bot_count = RuleI(Bots, CreationLimit);
|
||||
|
||||
uint32 bot_count = 0;
|
||||
if (!botdb.QueryBotCount(c->CharacterID(), bot_count)) {
|
||||
if (!database.botdb.QueryBotCount(c->CharacterID(), bot_count)) {
|
||||
c->Message(m_fail, "%s", BotDatabase::fail::QueryBotCount());
|
||||
return;
|
||||
}
|
||||
@@ -4244,18 +4264,18 @@ void bot_subcommand_bot_clone(Client *c, const Seperator *sep)
|
||||
}
|
||||
|
||||
uint32 clone_id = 0;
|
||||
if (!botdb.CreateCloneBot(c->CharacterID(), my_bot->GetBotID(), bot_name, clone_id) || !clone_id) {
|
||||
if (!database.botdb.CreateCloneBot(c->CharacterID(), my_bot->GetBotID(), bot_name, clone_id) || !clone_id) {
|
||||
c->Message(m_fail, "%s '%s'", BotDatabase::fail::CreateCloneBot(), bot_name.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
int clone_stance = BotStancePassive;
|
||||
if (!botdb.LoadStance(my_bot->GetBotID(), clone_stance))
|
||||
int clone_stance = EQEmu::constants::stancePassive;
|
||||
if (!database.botdb.LoadStance(my_bot->GetBotID(), clone_stance))
|
||||
c->Message(m_fail, "%s for bot '%s'", BotDatabase::fail::LoadStance(), my_bot->GetCleanName());
|
||||
if (!botdb.SaveStance(clone_id, clone_stance))
|
||||
if (!database.botdb.SaveStance(clone_id, clone_stance))
|
||||
c->Message(m_fail, "%s for clone '%s'", BotDatabase::fail::SaveStance(), bot_name.c_str());
|
||||
|
||||
if (!botdb.CreateCloneBotInventory(c->CharacterID(), my_bot->GetBotID(), clone_id))
|
||||
if (!database.botdb.CreateCloneBotInventory(c->CharacterID(), my_bot->GetBotID(), clone_id))
|
||||
c->Message(m_fail, "%s for clone '%s'", BotDatabase::fail::CreateCloneBotInventory(), bot_name.c_str());
|
||||
|
||||
c->Message(m_action, "Bot '%s' was successfully cloned to bot '%s'", my_bot->GetCleanName(), bot_name.c_str());
|
||||
@@ -4503,11 +4523,11 @@ void bot_subcommand_bot_dye_armor(Client *c, const Seperator *sep)
|
||||
|
||||
if (ab_type == ActionableBots::ABT_All) {
|
||||
if (dye_all) {
|
||||
if (!botdb.SaveAllArmorColors(c->CharacterID(), rgb_value))
|
||||
if (!database.botdb.SaveAllArmorColors(c->CharacterID(), rgb_value))
|
||||
c->Message(m_fail, "%s", BotDatabase::fail::SaveAllArmorColors());
|
||||
}
|
||||
else {
|
||||
if (!botdb.SaveAllArmorColorBySlot(c->CharacterID(), slot_id, rgb_value))
|
||||
if (!database.botdb.SaveAllArmorColorBySlot(c->CharacterID(), slot_id, rgb_value))
|
||||
c->Message(m_fail, "%s", BotDatabase::fail::SaveAllArmorColorBySlot());
|
||||
}
|
||||
}
|
||||
@@ -4656,7 +4676,7 @@ void bot_subcommand_bot_follow_distance(Client *c, const Seperator *sep)
|
||||
continue;
|
||||
|
||||
bot_iter->SetFollowDistance(bfd);
|
||||
if (ab_type != ActionableBots::ABT_All && !botdb.SaveFollowDistance(c->CharacterID(), bot_iter->GetBotID(), bfd)) {
|
||||
if (ab_type != ActionableBots::ABT_All && !database.botdb.SaveFollowDistance(c->CharacterID(), bot_iter->GetBotID(), bfd)) {
|
||||
c->Message(m_fail, "%s for '%s'", BotDatabase::fail::SaveFollowDistance(), bot_iter->GetCleanName());
|
||||
return;
|
||||
}
|
||||
@@ -4665,7 +4685,7 @@ void bot_subcommand_bot_follow_distance(Client *c, const Seperator *sep)
|
||||
}
|
||||
|
||||
if (ab_type == ActionableBots::ABT_All) {
|
||||
if (!botdb.SaveAllFollowDistances(c->CharacterID(), bfd)) {
|
||||
if (!database.botdb.SaveAllFollowDistances(c->CharacterID(), bfd)) {
|
||||
c->Message(m_fail, "%s", BotDatabase::fail::SaveAllFollowDistances());
|
||||
return;
|
||||
}
|
||||
@@ -4834,7 +4854,7 @@ void bot_subcommand_bot_inspect_message(Client *c, const Seperator *sep)
|
||||
if (set_flag)
|
||||
memcpy(bot_message_struct, client_message_struct, sizeof(InspectMessage_Struct));
|
||||
|
||||
if (ab_type != ActionableBots::ABT_All && !botdb.SaveInspectMessage(bot_iter->GetBotID(), *bot_message_struct)) {
|
||||
if (ab_type != ActionableBots::ABT_All && !database.botdb.SaveInspectMessage(bot_iter->GetBotID(), *bot_message_struct)) {
|
||||
c->Message(m_fail, "%s for '%s'", BotDatabase::fail::SaveInspectMessage(), bot_iter->GetCleanName());
|
||||
return;
|
||||
}
|
||||
@@ -4848,7 +4868,7 @@ void bot_subcommand_bot_inspect_message(Client *c, const Seperator *sep)
|
||||
if (set_flag)
|
||||
memcpy(&bot_message_struct, client_message_struct, sizeof(InspectMessage_Struct));
|
||||
|
||||
if (!botdb.SaveAllInspectMessages(c->CharacterID(), bot_message_struct)) {
|
||||
if (!database.botdb.SaveAllInspectMessages(c->CharacterID(), bot_message_struct)) {
|
||||
c->Message(m_fail, "%s", BotDatabase::fail::SaveAllInspectMessages());
|
||||
return;
|
||||
}
|
||||
@@ -4904,7 +4924,7 @@ void bot_subcommand_bot_list(Client *c, const Seperator *sep)
|
||||
}
|
||||
|
||||
std::list<BotsAvailableList> bots_list;
|
||||
if (!botdb.LoadBotsList(c->CharacterID(), bots_list)) {
|
||||
if (!database.botdb.LoadBotsList(c->CharacterID(), bots_list)) {
|
||||
c->Message(m_fail, "%s", BotDatabase::fail::LoadBotsList());
|
||||
return;
|
||||
}
|
||||
@@ -5061,7 +5081,7 @@ void bot_subcommand_bot_spawn(Client *c, const Seperator *sep)
|
||||
|
||||
if (RuleB(Bots, QuestableSpawnLimit) && !c->GetGM()) {
|
||||
int allowed_bot_count = 0;
|
||||
if (!botdb.LoadQuestableSpawnCount(c->CharacterID(), allowed_bot_count)) {
|
||||
if (!database.botdb.LoadQuestableSpawnCount(c->CharacterID(), allowed_bot_count)) {
|
||||
c->Message(m_fail, "%s", BotDatabase::fail::LoadQuestableSpawnCount());
|
||||
return;
|
||||
}
|
||||
@@ -5082,7 +5102,7 @@ void bot_subcommand_bot_spawn(Client *c, const Seperator *sep)
|
||||
std::string bot_name = sep->arg[1];
|
||||
|
||||
uint32 bot_id = 0;
|
||||
if (!botdb.LoadBotID(c->CharacterID(), bot_name, bot_id)) {
|
||||
if (!database.botdb.LoadBotID(c->CharacterID(), bot_name, bot_id)) {
|
||||
c->Message(m_fail, "%s for '%s'", BotDatabase::fail::LoadBotID(), bot_name.c_str());
|
||||
return;
|
||||
}
|
||||
@@ -5160,29 +5180,34 @@ void bot_subcommand_bot_stance(Client *c, const Seperator *sep)
|
||||
if (helper_command_alias_fail(c, "bot_subcommand_bot_stance", sep->arg[0], "botstance"))
|
||||
return;
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
c->Message(m_usage, "usage: %s [current | value: 0-6] ([actionable: target | byname] ([actionable_name]))", sep->arg[0]);
|
||||
c->Message(m_usage, "usage: %s [current | value: 1-9] ([actionable: target | byname] ([actionable_name]))", sep->arg[0]);
|
||||
c->Message(m_note, "value: %u(%s), %u(%s), %u(%s), %u(%s), %u(%s), %u(%s), %u(%s)",
|
||||
BotStancePassive, GetBotStanceName(BotStancePassive),
|
||||
BotStanceBalanced, GetBotStanceName(BotStanceBalanced),
|
||||
BotStanceEfficient, GetBotStanceName(BotStanceEfficient),
|
||||
BotStanceReactive, GetBotStanceName(BotStanceReactive),
|
||||
BotStanceAggressive, GetBotStanceName(BotStanceAggressive),
|
||||
BotStanceBurn, GetBotStanceName(BotStanceBurn),
|
||||
BotStanceBurnAE, GetBotStanceName(BotStanceBurnAE)
|
||||
EQEmu::constants::stancePassive, EQEmu::constants::GetStanceName(EQEmu::constants::stancePassive),
|
||||
EQEmu::constants::stanceBalanced, EQEmu::constants::GetStanceName(EQEmu::constants::stanceBalanced),
|
||||
EQEmu::constants::stanceEfficient, EQEmu::constants::GetStanceName(EQEmu::constants::stanceEfficient),
|
||||
EQEmu::constants::stanceReactive, EQEmu::constants::GetStanceName(EQEmu::constants::stanceReactive),
|
||||
EQEmu::constants::stanceAggressive, EQEmu::constants::GetStanceName(EQEmu::constants::stanceAggressive),
|
||||
EQEmu::constants::stanceAssist, EQEmu::constants::GetStanceName(EQEmu::constants::stanceAssist),
|
||||
EQEmu::constants::stanceBurn, EQEmu::constants::GetStanceName(EQEmu::constants::stanceBurn),
|
||||
EQEmu::constants::stanceEfficient2, EQEmu::constants::GetStanceName(EQEmu::constants::stanceEfficient2),
|
||||
EQEmu::constants::stanceBurnAE, EQEmu::constants::GetStanceName(EQEmu::constants::stanceBurnAE)
|
||||
);
|
||||
return;
|
||||
}
|
||||
int ab_mask = (ActionableBots::ABM_Target | ActionableBots::ABM_ByName);
|
||||
|
||||
bool current_flag = false;
|
||||
auto bst = BotStanceUnknown;
|
||||
auto bst = EQEmu::constants::stanceUnknown;
|
||||
|
||||
if (!strcasecmp(sep->arg[1], "current"))
|
||||
current_flag = true;
|
||||
else if (sep->IsNumber(1))
|
||||
bst = VALIDBOTSTANCE(atoi(sep->arg[1]));
|
||||
else if (sep->IsNumber(1)) {
|
||||
bst = (EQEmu::constants::StanceType)atoi(sep->arg[1]);
|
||||
if (bst < EQEmu::constants::stanceUnknown || bst > EQEmu::constants::stanceBurnAE)
|
||||
bst = EQEmu::constants::stanceUnknown;
|
||||
}
|
||||
|
||||
if (!current_flag && bst == BotStanceUnknown) {
|
||||
if (!current_flag && bst == EQEmu::constants::stanceUnknown) {
|
||||
c->Message(m_fail, "A [current] argument or valid numeric [value] is required to use this command");
|
||||
return;
|
||||
}
|
||||
@@ -5200,7 +5225,12 @@ void bot_subcommand_bot_stance(Client *c, const Seperator *sep)
|
||||
bot_iter->Save();
|
||||
}
|
||||
|
||||
Bot::BotGroupSay(bot_iter, "My current stance is '%s' (%u)", GetBotStanceName(bot_iter->GetBotStance()), bot_iter->GetBotStance());
|
||||
Bot::BotGroupSay(
|
||||
bot_iter,
|
||||
"My current stance is '%s' (%i)",
|
||||
EQEmu::constants::GetStanceName(bot_iter->GetBotStance()),
|
||||
bot_iter->GetBotStance()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5245,7 +5275,7 @@ void bot_subcommand_bot_stop_melee_level(Client *c, const Seperator *sep)
|
||||
// [reset] falls through with initialization value
|
||||
|
||||
my_bot->SetStopMeleeLevel(sml);
|
||||
if (!botdb.SaveStopMeleeLevel(c->CharacterID(), my_bot->GetBotID(), sml))
|
||||
if (!database.botdb.SaveStopMeleeLevel(c->CharacterID(), my_bot->GetBotID(), sml))
|
||||
c->Message(m_fail, "%s for '%s'", BotDatabase::fail::SaveStopMeleeLevel(), my_bot->GetCleanName());
|
||||
|
||||
c->Message(m_action, "Successfully set stop melee level for %s to %u", my_bot->GetCleanName(), sml);
|
||||
@@ -5414,7 +5444,7 @@ void bot_subcommand_bot_toggle_helm(Client *c, const Seperator *sep)
|
||||
bot_iter->SetShowHelm(helm_state);
|
||||
|
||||
if (ab_type != ActionableBots::ABT_All) {
|
||||
if (!botdb.SaveHelmAppearance(c->CharacterID(), bot_iter->GetBotID(), bot_iter->GetShowHelm())) {
|
||||
if (!database.botdb.SaveHelmAppearance(c->CharacterID(), bot_iter->GetBotID(), bot_iter->GetShowHelm())) {
|
||||
c->Message(m_unknown, "%s for '%s'", bot_iter->GetCleanName());
|
||||
return;
|
||||
}
|
||||
@@ -5436,11 +5466,11 @@ void bot_subcommand_bot_toggle_helm(Client *c, const Seperator *sep)
|
||||
if (ab_type == ActionableBots::ABT_All) {
|
||||
std::string query;
|
||||
if (toggle_helm) {
|
||||
if (!botdb.ToggleAllHelmAppearances(c->CharacterID()))
|
||||
if (!database.botdb.ToggleAllHelmAppearances(c->CharacterID()))
|
||||
c->Message(m_fail, "%s", BotDatabase::fail::ToggleAllHelmAppearances());
|
||||
}
|
||||
else {
|
||||
if (!botdb.SaveAllHelmAppearances(c->CharacterID(), helm_state))
|
||||
if (!database.botdb.SaveAllHelmAppearances(c->CharacterID(), helm_state))
|
||||
c->Message(m_fail, "%s", BotDatabase::fail::SaveAllHelmAppearances());
|
||||
}
|
||||
|
||||
@@ -5522,7 +5552,7 @@ void bot_subcommand_bot_update(Client *c, const Seperator *sep)
|
||||
continue;
|
||||
|
||||
bot_iter->SetPetChooser(false);
|
||||
bot_iter->CalcBotStats((sbl.size() == 1));
|
||||
bot_iter->CalcBotStats(c->GetBotOptionStatsUpdate());
|
||||
bot_iter->SendAppearancePacket(AT_WhoLevel, bot_iter->GetLevel(), true, true);
|
||||
++bot_count;
|
||||
}
|
||||
@@ -5599,7 +5629,7 @@ void bot_subcommand_botgroup_add_member(Client *c, const Seperator *sep)
|
||||
}
|
||||
|
||||
uint32 botgroup_id = 0;
|
||||
if (!botdb.LoadBotGroupIDByMemberID(new_member->GetBotID(), botgroup_id)) {
|
||||
if (!database.botdb.LoadBotGroupIDByMemberID(new_member->GetBotID(), botgroup_id)) {
|
||||
c->Message(m_fail, "%s for '%s'", BotDatabase::fail::LoadBotGroupIDByMemberID(), new_member->GetCleanName());
|
||||
return;
|
||||
}
|
||||
@@ -5629,7 +5659,7 @@ void bot_subcommand_botgroup_add_member(Client *c, const Seperator *sep)
|
||||
}
|
||||
|
||||
botgroup_id = 0;
|
||||
if (!botdb.LoadBotGroupIDByLeaderID(botgroup_leader->GetBotID(), botgroup_id)) {
|
||||
if (!database.botdb.LoadBotGroupIDByLeaderID(botgroup_leader->GetBotID(), botgroup_id)) {
|
||||
c->Message(m_fail, "%s for '%s'", BotDatabase::fail::LoadBotGroupIDByLeaderID(), botgroup_leader->GetCleanName());
|
||||
return;
|
||||
}
|
||||
@@ -5645,14 +5675,14 @@ void bot_subcommand_botgroup_add_member(Client *c, const Seperator *sep)
|
||||
|
||||
database.SetGroupID(new_member->GetName(), group_inst->GetID(), new_member->GetBotID());
|
||||
|
||||
if (!botdb.AddMemberToBotGroup(botgroup_leader->GetBotID(), new_member->GetBotID())) {
|
||||
if (!database.botdb.AddMemberToBotGroup(botgroup_leader->GetBotID(), new_member->GetBotID())) {
|
||||
c->Message(m_fail, "%s - %s->%s", BotDatabase::fail::AddMemberToBotGroup(), new_member->GetCleanName(), botgroup_leader->GetCleanName());
|
||||
Bot::RemoveBotFromGroup(new_member, botgroup_leader->GetGroup());
|
||||
return;
|
||||
}
|
||||
|
||||
std::string botgroup_name;
|
||||
if (!botdb.LoadBotGroupNameByLeaderID(botgroup_leader->GetBotID(), botgroup_name))
|
||||
if (!database.botdb.LoadBotGroupNameByLeaderID(botgroup_leader->GetBotID(), botgroup_name))
|
||||
c->Message(m_fail, "%s", BotDatabase::fail::LoadBotGroupNameByLeaderID());
|
||||
|
||||
c->Message(m_action, "Successfully added %s to bot-group %s", new_member->GetCleanName(), botgroup_name.c_str());
|
||||
@@ -5674,7 +5704,7 @@ void bot_subcommand_botgroup_create(Client *c, const Seperator *sep)
|
||||
}
|
||||
|
||||
bool extant_flag = false;
|
||||
if (!botdb.QueryBotGroupExistence(botgroup_name_arg, extant_flag)) {
|
||||
if (!database.botdb.QueryBotGroupExistence(botgroup_name_arg, extant_flag)) {
|
||||
c->Message(m_fail, "%s for '%s'", BotDatabase::fail::QueryBotGroupExistence(), botgroup_name_arg.c_str());
|
||||
return;
|
||||
}
|
||||
@@ -5704,7 +5734,7 @@ void bot_subcommand_botgroup_create(Client *c, const Seperator *sep)
|
||||
}
|
||||
|
||||
uint32 botgroup_id = 0;
|
||||
if (!botdb.LoadBotGroupIDByLeaderID(botgroup_leader->GetBotID(), botgroup_id)) {
|
||||
if (!database.botdb.LoadBotGroupIDByLeaderID(botgroup_leader->GetBotID(), botgroup_id)) {
|
||||
c->Message(m_fail, "%s for '%s'", BotDatabase::fail::LoadBotGroupIDByLeaderID(), botgroup_leader->GetCleanName());
|
||||
return;
|
||||
}
|
||||
@@ -5714,7 +5744,7 @@ void bot_subcommand_botgroup_create(Client *c, const Seperator *sep)
|
||||
}
|
||||
|
||||
botgroup_id = 0;
|
||||
if (!botdb.LoadBotGroupIDByMemberID(botgroup_leader->GetBotID(), botgroup_id)) {
|
||||
if (!database.botdb.LoadBotGroupIDByMemberID(botgroup_leader->GetBotID(), botgroup_id)) {
|
||||
c->Message(m_fail, "%s for '%s'", BotDatabase::fail::LoadBotGroupIDByMemberID(), botgroup_leader->GetCleanName());
|
||||
return;
|
||||
}
|
||||
@@ -5729,7 +5759,7 @@ void bot_subcommand_botgroup_create(Client *c, const Seperator *sep)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!botdb.CreateBotGroup(botgroup_name_arg, botgroup_leader->GetBotID())) {
|
||||
if (!database.botdb.CreateBotGroup(botgroup_name_arg, botgroup_leader->GetBotID())) {
|
||||
c->Message(m_fail, "%s '%s'", BotDatabase::fail::CreateBotGroup(), botgroup_name_arg.c_str());
|
||||
safe_delete(group_inst);
|
||||
return;
|
||||
@@ -5759,7 +5789,7 @@ void bot_subcommand_botgroup_delete(Client *c, const Seperator *sep)
|
||||
}
|
||||
|
||||
uint32 botgroup_id = 0;
|
||||
if (!botdb.LoadBotGroupIDForLoadBotGroup(c->CharacterID(), botgroup_name_arg, botgroup_id)) {
|
||||
if (!database.botdb.LoadBotGroupIDForLoadBotGroup(c->CharacterID(), botgroup_name_arg, botgroup_id)) {
|
||||
c->Message(m_fail, "%s for '%s'", BotDatabase::fail::LoadBotGroupIDForLoadBotGroup(), botgroup_name_arg.c_str());
|
||||
return;
|
||||
}
|
||||
@@ -5769,7 +5799,7 @@ void bot_subcommand_botgroup_delete(Client *c, const Seperator *sep)
|
||||
}
|
||||
|
||||
uint32 leader_id = 0;
|
||||
if (!botdb.LoadLeaderIDByBotGroupID(botgroup_id, leader_id)) {
|
||||
if (!database.botdb.LoadLeaderIDByBotGroupID(botgroup_id, leader_id)) {
|
||||
c->Message(m_fail, "%s for '%s'", BotDatabase::fail::LoadLeaderIDByBotGroupID(), botgroup_name_arg.c_str());
|
||||
return;
|
||||
}
|
||||
@@ -5783,7 +5813,7 @@ void bot_subcommand_botgroup_delete(Client *c, const Seperator *sep)
|
||||
MyBots::PopulateSBL_BySpawnedBots(c, sbl);
|
||||
|
||||
std::map<uint32, std::list<uint32>> member_list;
|
||||
if (!botdb.LoadBotGroup(botgroup_name_arg, member_list)) {
|
||||
if (!database.botdb.LoadBotGroup(botgroup_name_arg, member_list)) {
|
||||
c->Message(m_fail, "%s '%s'", BotDatabase::fail::LoadBotGroup(), botgroup_name_arg.c_str());
|
||||
return;
|
||||
}
|
||||
@@ -5807,7 +5837,7 @@ void bot_subcommand_botgroup_delete(Client *c, const Seperator *sep)
|
||||
Bot::RemoveBotFromGroup(group_member, group_member->GetGroup());
|
||||
}
|
||||
|
||||
if (!botdb.DeleteBotGroup(leader_id)) {
|
||||
if (!database.botdb.DeleteBotGroup(leader_id)) {
|
||||
c->Message(m_fail, "%s '%s'", BotDatabase::fail::DeleteBotGroup(), botgroup_name_arg.c_str());
|
||||
return;
|
||||
}
|
||||
@@ -5825,7 +5855,7 @@ void bot_subcommand_botgroup_list(Client *c, const Seperator *sep)
|
||||
}
|
||||
|
||||
std::list<std::pair<std::string, std::string>> botgroups_list;
|
||||
if (!botdb.LoadBotGroupsListByOwnerID(c->CharacterID(), botgroups_list)) {
|
||||
if (!database.botdb.LoadBotGroupsListByOwnerID(c->CharacterID(), botgroups_list)) {
|
||||
c->Message(m_fail, "%s", BotDatabase::fail::LoadBotGroupsListByOwnerID());
|
||||
return;
|
||||
}
|
||||
@@ -5857,7 +5887,7 @@ void bot_subcommand_botgroup_load(Client *c, const Seperator *sep)
|
||||
}
|
||||
|
||||
bool extant_flag = false;
|
||||
if (!botdb.QueryBotGroupExistence(botgroup_name_arg, extant_flag)) {
|
||||
if (!database.botdb.QueryBotGroupExistence(botgroup_name_arg, extant_flag)) {
|
||||
c->Message(m_fail, "%s for '%s'", BotDatabase::fail::QueryBotGroupExistence(), botgroup_name_arg.c_str());
|
||||
return;
|
||||
}
|
||||
@@ -5887,13 +5917,13 @@ void bot_subcommand_botgroup_load(Client *c, const Seperator *sep)
|
||||
}
|
||||
|
||||
uint32 botgroup_id = 0;
|
||||
if (!botdb.LoadBotGroupIDForLoadBotGroup(c->CharacterID(), botgroup_name_arg, botgroup_id) || !botgroup_id) {
|
||||
if (!database.botdb.LoadBotGroupIDForLoadBotGroup(c->CharacterID(), botgroup_name_arg, botgroup_id) || !botgroup_id) {
|
||||
c->Message(m_fail, "%s for '%s'", BotDatabase::fail::LoadBotGroupIDForLoadBotGroup(), botgroup_name_arg.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
std::map<uint32, std::list<uint32>> member_list;
|
||||
if (!botdb.LoadBotGroup(botgroup_name_arg, member_list)) {
|
||||
if (!database.botdb.LoadBotGroup(botgroup_name_arg, member_list)) {
|
||||
c->Message(m_fail, "%s for '%s'", BotDatabase::fail::LoadBotGroup(), botgroup_name_arg.c_str());
|
||||
return;
|
||||
}
|
||||
@@ -5906,7 +5936,7 @@ void bot_subcommand_botgroup_load(Client *c, const Seperator *sep)
|
||||
|
||||
if (RuleB(Bots, QuestableSpawnLimit)) {
|
||||
int allowed_bot_count = 0;
|
||||
if (!botdb.LoadQuestableSpawnCount(c->CharacterID(), allowed_bot_count)) {
|
||||
if (!database.botdb.LoadQuestableSpawnCount(c->CharacterID(), allowed_bot_count)) {
|
||||
c->Message(m_fail, "%s", BotDatabase::fail::LoadQuestableSpawnCount());
|
||||
return;
|
||||
}
|
||||
@@ -5929,7 +5959,7 @@ void bot_subcommand_botgroup_load(Client *c, const Seperator *sep)
|
||||
}
|
||||
|
||||
uint32 leader_id = 0;
|
||||
if (!botdb.LoadLeaderIDByBotGroupName(botgroup_name_arg, leader_id)) {
|
||||
if (!database.botdb.LoadLeaderIDByBotGroupName(botgroup_name_arg, leader_id)) {
|
||||
c->Message(m_fail, "%s for '%s'", BotDatabase::fail::LoadLeaderIDByBotGroupName(), botgroup_name_arg.c_str());
|
||||
return;
|
||||
}
|
||||
@@ -6014,7 +6044,7 @@ void bot_subcommand_botgroup_remove_member(Client *c, const Seperator *sep)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!botdb.RemoveMemberFromBotGroup(group_member->GetBotID())) {
|
||||
if (!database.botdb.RemoveMemberFromBotGroup(group_member->GetBotID())) {
|
||||
c->Message(m_fail, "%s - '%s'", BotDatabase::fail::RemoveMemberFromBotGroup(), group_member->GetCleanName());
|
||||
return;
|
||||
}
|
||||
@@ -6636,7 +6666,7 @@ void bot_subcommand_heal_rotation_create(Client *c, const Seperator *sep)
|
||||
bool member_fail = false;
|
||||
bool target_fail = false;
|
||||
|
||||
if (!botdb.LoadHealRotation(creator_member, member_list, target_list, load_flag, member_fail, target_fail))
|
||||
if (!database.botdb.LoadHealRotation(creator_member, member_list, target_list, load_flag, member_fail, target_fail))
|
||||
c->Message(m_fail, "%s", BotDatabase::fail::LoadHealRotation());
|
||||
|
||||
if (!load_flag) {
|
||||
@@ -6709,7 +6739,7 @@ void bot_subcommand_heal_rotation_delete(Client *c, const Seperator *sep)
|
||||
}
|
||||
|
||||
if (all_flag) {
|
||||
if (botdb.DeleteAllHealRotations(c->CharacterID()))
|
||||
if (database.botdb.DeleteAllHealRotations(c->CharacterID()))
|
||||
c->Message(m_action, "Succeeded in deleting all heal rotations");
|
||||
else
|
||||
c->Message(m_fail, "%s", BotDatabase::fail::DeleteAllHealRotations());
|
||||
@@ -6732,7 +6762,7 @@ void bot_subcommand_heal_rotation_delete(Client *c, const Seperator *sep)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!botdb.DeleteHealRotation(current_member->GetBotID())) {
|
||||
if (!database.botdb.DeleteHealRotation(current_member->GetBotID())) {
|
||||
c->Message(m_fail, "%s", BotDatabase::fail::DeleteHealRotation());
|
||||
return;
|
||||
}
|
||||
@@ -7019,7 +7049,7 @@ void bot_subcommand_heal_rotation_save(Client *c, const Seperator *sep)
|
||||
|
||||
bool member_fail = false;
|
||||
bool target_fail = false;
|
||||
if (!botdb.SaveHealRotation(current_member, member_fail, target_fail)) {
|
||||
if (!database.botdb.SaveHealRotation(current_member, member_fail, target_fail)) {
|
||||
c->Message(m_fail, "%s", BotDatabase::fail::SaveHealRotation());
|
||||
return;
|
||||
}
|
||||
@@ -7220,7 +7250,7 @@ void bot_subcommand_inventory_list(Client *c, const Seperator *sep)
|
||||
|
||||
inst = my_bot->CastToBot()->GetBotItem(i);
|
||||
if (!inst || !inst->GetItem()) {
|
||||
c->Message(m_message, "I need something for my %s (slot %i)", GetBotEquipSlotName(i), i);
|
||||
c->Message(m_message, "I need something for my %s (slot %i)", EQEmu::invslot::GetInvPossessionsSlotName(i), i);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -7230,13 +7260,13 @@ void bot_subcommand_inventory_list(Client *c, const Seperator *sep)
|
||||
}
|
||||
|
||||
linker.SetItemInst(inst);
|
||||
c->Message(m_message, "Using %s in my %s (slot %i)", linker.GenerateLink().c_str(), GetBotEquipSlotName(i), i);
|
||||
c->Message(m_message, "Using %s in my %s (slot %i)", linker.GenerateLink().c_str(), EQEmu::invslot::GetInvPossessionsSlotName(i), i);
|
||||
|
||||
++inventory_count;
|
||||
}
|
||||
|
||||
uint32 database_count = 0;
|
||||
if (!botdb.QueryInventoryCount(my_bot->GetBotID(), database_count))
|
||||
if (!database.botdb.QueryInventoryCount(my_bot->GetBotID(), database_count))
|
||||
c->Message(m_unknown, "%s", BotDatabase::fail::QueryInventoryCount());
|
||||
|
||||
if (inventory_count != database_count)
|
||||
@@ -7311,7 +7341,7 @@ void bot_subcommand_inventory_remove(Client *c, const Seperator *sep)
|
||||
}
|
||||
|
||||
my_bot->BotRemoveEquipItem(slotId);
|
||||
my_bot->CalcBotStats();
|
||||
my_bot->CalcBotStats(c->GetBotOptionStatsUpdate());
|
||||
}
|
||||
|
||||
switch (slotId) {
|
||||
@@ -7333,14 +7363,14 @@ void bot_subcommand_inventory_remove(Client *c, const Seperator *sep)
|
||||
case EQEmu::invslot::slotWaist:
|
||||
case EQEmu::invslot::slotPowerSource:
|
||||
case EQEmu::invslot::slotAmmo:
|
||||
c->Message(m_message, "My %s is %s unequipped", GetBotEquipSlotName(slotId), ((itm) ? ("now") : ("already")));
|
||||
c->Message(m_message, "My %s is %s unequipped", EQEmu::invslot::GetInvPossessionsSlotName(slotId), ((itm) ? ("now") : ("already")));
|
||||
break;
|
||||
case EQEmu::invslot::slotShoulders:
|
||||
case EQEmu::invslot::slotArms:
|
||||
case EQEmu::invslot::slotHands:
|
||||
case EQEmu::invslot::slotLegs:
|
||||
case EQEmu::invslot::slotFeet:
|
||||
c->Message(m_message, "My %s are %s unequipped", GetBotEquipSlotName(slotId), ((itm) ? ("now") : ("already")));
|
||||
c->Message(m_message, "My %s are %s unequipped", EQEmu::invslot::GetInvPossessionsSlotName(slotId), ((itm) ? ("now") : ("already")));
|
||||
break;
|
||||
default:
|
||||
c->Message(m_fail, "I'm soo confused...");
|
||||
@@ -7383,7 +7413,7 @@ void bot_subcommand_inventory_window(Client *c, const Seperator *sep)
|
||||
item = inst->GetItem();
|
||||
|
||||
window_text.append("<c \"#FFFFFF\">");
|
||||
window_text.append(GetBotEquipSlotName(i));
|
||||
window_text.append(EQEmu::invslot::GetInvPossessionsSlotName(i));
|
||||
window_text.append(": ");
|
||||
if (item) {
|
||||
//window_text.append("</c>");
|
||||
@@ -7405,6 +7435,37 @@ void bot_subcommand_inventory_window(Client *c, const Seperator *sep)
|
||||
c->SendPopupToClient(window_title.c_str(), window_text.c_str());
|
||||
}
|
||||
|
||||
void bot_subcommand_pet_get_lost(Client *c, const Seperator *sep)
|
||||
{
|
||||
if (helper_command_alias_fail(c, "bot_subcommand_pet_get_lost", sep->arg[0], "petgetlost"))
|
||||
return;
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
c->Message(m_usage, "usage: %s ([actionable: target | byname | ownergroup | botgroup | targetgroup | namesgroup | healrotation | spawned] ([actionable_name]))", sep->arg[0]);
|
||||
return;
|
||||
}
|
||||
int ab_mask = ActionableBots::ABM_NoFilter;
|
||||
|
||||
std::list<Bot*> sbl;
|
||||
if (ActionableBots::PopulateSBL(c, sep->arg[1], sbl, ab_mask, sep->arg[2]) == ActionableBots::ABT_None)
|
||||
return;
|
||||
|
||||
int summoned_pet = 0;
|
||||
for (auto bot_iter : sbl) {
|
||||
if (!bot_iter->GetPet() || bot_iter->GetPet()->IsCharmed())
|
||||
continue;
|
||||
|
||||
bot_iter->GetPet()->Say_StringID(PET_GETLOST_STRING);
|
||||
bot_iter->GetPet()->Depop(false);
|
||||
bot_iter->SetPetID(0);
|
||||
database.botdb.DeletePetItems(bot_iter->GetBotID());
|
||||
database.botdb.DeletePetBuffs(bot_iter->GetBotID());
|
||||
database.botdb.DeletePetStats(bot_iter->GetBotID());
|
||||
++summoned_pet;
|
||||
}
|
||||
|
||||
c->Message(m_action, "%i of your bots released their summoned pet%s", summoned_pet, (summoned_pet == 1) ? "" : "s");
|
||||
}
|
||||
|
||||
void bot_subcommand_pet_remove(Client *c, const Seperator *sep)
|
||||
{
|
||||
if (helper_command_alias_fail(c, "bot_subcommand_pet_remove", sep->arg[0], "petremove"))
|
||||
@@ -7656,7 +7717,7 @@ uint32 helper_bot_create(Client *bot_owner, std::string bot_name, uint8 bot_clas
|
||||
}
|
||||
|
||||
bool available_flag = false;
|
||||
if (!botdb.QueryNameAvailablity(bot_name, available_flag)) {
|
||||
if (!database.botdb.QueryNameAvailablity(bot_name, available_flag)) {
|
||||
bot_owner->Message(m_fail, "%s for '%s'", BotDatabase::fail::QueryNameAvailablity(), bot_name.c_str());
|
||||
return bot_id;
|
||||
}
|
||||
@@ -7698,7 +7759,7 @@ uint32 helper_bot_create(Client *bot_owner, std::string bot_name, uint8 bot_clas
|
||||
uint32 max_bot_count = RuleI(Bots, CreationLimit);
|
||||
|
||||
uint32 bot_count = 0;
|
||||
if (!botdb.QueryBotCount(bot_owner->CharacterID(), bot_count)) {
|
||||
if (!database.botdb.QueryBotCount(bot_owner->CharacterID(), bot_count)) {
|
||||
bot_owner->Message(m_fail, "%s", BotDatabase::fail::QueryBotCount());
|
||||
return bot_id;
|
||||
}
|
||||
@@ -7707,16 +7768,7 @@ uint32 helper_bot_create(Client *bot_owner, std::string bot_name, uint8 bot_clas
|
||||
return bot_id;
|
||||
}
|
||||
|
||||
auto DefaultNPCTypeStruct = Bot::CreateDefaultNPCTypeStructForBot(
|
||||
bot_name.c_str(),
|
||||
"",
|
||||
bot_owner->GetLevel(),
|
||||
bot_race,
|
||||
bot_class,
|
||||
bot_gender
|
||||
);
|
||||
|
||||
auto my_bot = new Bot(DefaultNPCTypeStruct, bot_owner);
|
||||
auto my_bot = new Bot(Bot::CreateDefaultNPCTypeStructForBot(bot_name.c_str(), "", bot_owner->GetLevel(), bot_race, bot_class, bot_gender), bot_owner);
|
||||
|
||||
if (!my_bot->Save()) {
|
||||
bot_owner->Message(m_unknown, "Failed to create '%s' due to unknown cause", my_bot->GetCleanName());
|
||||
|
||||
@@ -652,6 +652,7 @@ void bot_subcommand_inventory_give(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_inventory_list(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_inventory_remove(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_inventory_window(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_pet_get_lost(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_pet_remove(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_pet_set_type(Client *c, const Seperator *sep);
|
||||
void bot_subcommand_portal(Client *c, const Seperator *sep);
|
||||
|
||||
+139
-154
@@ -23,48 +23,17 @@
|
||||
#include "../common/string_util.h"
|
||||
#include "../common/eqemu_logsys.h"
|
||||
|
||||
#include "bot_database.h"
|
||||
#include "zonedb.h"
|
||||
#include "bot.h"
|
||||
#include "client.h"
|
||||
|
||||
|
||||
BotDatabase botdb;
|
||||
|
||||
|
||||
BotDatabase::BotDatabase()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
BotDatabase::BotDatabase(const char* host, const char* user, const char* passwd, const char* database, uint32 port)
|
||||
{
|
||||
Connect(host, user, passwd, database, port);
|
||||
}
|
||||
|
||||
BotDatabase::~BotDatabase()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool BotDatabase::Connect(const char* host, const char* user, const char* passwd, const char* database, uint32 port) {
|
||||
uint32 errnum = 0;
|
||||
char errbuf[MYSQL_ERRMSG_SIZE];
|
||||
if (!Open(host, user, passwd, database, port, &errnum, errbuf)) {
|
||||
Log(Logs::General, Logs::Error, "Failed to connect to bot database: Error: %s", errbuf);
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
Log(Logs::General, Logs::Status, "Using bot database '%s' at %s:%d", database, host, port);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool BotDatabase::LoadBotCommandSettings(std::map<std::string, std::pair<uint8, std::vector<std::string>>> &bot_command_settings)
|
||||
{
|
||||
bot_command_settings.clear();
|
||||
|
||||
query = "SELECT `bot_command`, `access`, `aliases` FROM `bot_command_settings`";
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
|
||||
@@ -83,12 +52,8 @@ bool BotDatabase::LoadBotCommandSettings(std::map<std::string, std::pair<uint8,
|
||||
return true;
|
||||
}
|
||||
|
||||
static uint8 spell_casting_chances[MaxSpellTypes][PLAYER_CLASS_COUNT][MaxStances][cntHSND];
|
||||
|
||||
bool BotDatabase::LoadBotSpellCastingChances()
|
||||
{
|
||||
memset(spell_casting_chances, 0, sizeof(spell_casting_chances));
|
||||
|
||||
query =
|
||||
"SELECT"
|
||||
" `spell_type_index`,"
|
||||
@@ -113,20 +78,20 @@ bool BotDatabase::LoadBotSpellCastingChances()
|
||||
"FROM"
|
||||
" `bot_spell_casting_chances`";
|
||||
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success() || !results.RowCount())
|
||||
return false;
|
||||
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
uint8 spell_type_index = atoi(row[0]);
|
||||
if (spell_type_index >= MaxSpellTypes)
|
||||
if (spell_type_index >= Bot::SPELL_TYPE_COUNT)
|
||||
continue;
|
||||
uint8 class_index = atoi(row[1]);
|
||||
if (class_index < WARRIOR || class_index > BERSERKER)
|
||||
continue;
|
||||
--class_index;
|
||||
uint8 stance_index = atoi(row[2]);
|
||||
if (stance_index >= MaxStances)
|
||||
if (stance_index >= EQEmu::constants::STANCE_TYPE_COUNT)
|
||||
continue;
|
||||
|
||||
for (uint8 conditional_index = nHSND; conditional_index < cntHSND; ++conditional_index) {
|
||||
@@ -136,7 +101,7 @@ bool BotDatabase::LoadBotSpellCastingChances()
|
||||
if (value > 100)
|
||||
value = 100;
|
||||
|
||||
spell_casting_chances[spell_type_index][class_index][stance_index][conditional_index] = value;
|
||||
Bot::spell_casting_chances[spell_type_index][class_index][stance_index][conditional_index] = value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,7 +116,7 @@ bool BotDatabase::QueryNameAvailablity(const std::string& bot_name, bool& availa
|
||||
return false;
|
||||
|
||||
query = StringFormat("SELECT `id` FROM `vw_bot_character_mobs` WHERE `name` LIKE '%s' LIMIT 1", bot_name.c_str());
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
if (results.RowCount())
|
||||
@@ -168,7 +133,7 @@ bool BotDatabase::QueryBotCount(const uint32 owner_id, uint32& bot_count)
|
||||
return false;
|
||||
|
||||
query = StringFormat("SELECT COUNT(`bot_id`) FROM `bot_data` WHERE `owner_id` = '%i'", owner_id);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
if (!results.RowCount())
|
||||
@@ -204,7 +169,7 @@ bool BotDatabase::LoadBotsList(const uint32 owner_id, std::list<BotsAvailableLis
|
||||
return false;
|
||||
|
||||
query = StringFormat("SELECT `bot_id`, `name`, `class`, `level`, `race`, `gender` FROM `bot_data` WHERE `owner_id` = '%u'", owner_id);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
if (!results.RowCount())
|
||||
@@ -239,7 +204,7 @@ bool BotDatabase::LoadOwnerID(const std::string& bot_name, uint32& owner_id)
|
||||
return false;
|
||||
|
||||
query = StringFormat("SELECT `owner_id` FROM `bot_data` WHERE `name` = '%s' LIMIT 1", bot_name.c_str());
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
if (!results.RowCount())
|
||||
@@ -257,7 +222,7 @@ bool BotDatabase::LoadOwnerID(const uint32 bot_id, uint32& owner_id)
|
||||
return false;
|
||||
|
||||
query = StringFormat("SELECT `owner_id` FROM `bot_data` WHERE `bot_id` = '%u' LIMIT 1", bot_id);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
if (!results.RowCount())
|
||||
@@ -278,7 +243,7 @@ bool BotDatabase::LoadBotID(const uint32 owner_id, const std::string& bot_name,
|
||||
"SELECT `bot_id` FROM `bot_data` WHERE `owner_id` = '%u' AND `name` = '%s' LIMIT 1",
|
||||
owner_id, bot_name.c_str()
|
||||
);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
if (!results.RowCount())
|
||||
@@ -349,7 +314,7 @@ bool BotDatabase::LoadBot(const uint32 bot_id, Bot*& loaded_bot)
|
||||
bot_id
|
||||
);
|
||||
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
if (!results.RowCount())
|
||||
@@ -357,8 +322,8 @@ bool BotDatabase::LoadBot(const uint32 bot_id, Bot*& loaded_bot)
|
||||
|
||||
// TODO: Consider removing resists and basic attributes from the load query above since we're using defaultNPCType values instead
|
||||
auto row = results.begin();
|
||||
NPCType defaultNPCTypeStruct = Bot::CreateDefaultNPCTypeStructForBot(std::string(row[2]), std::string(row[3]), atoi(row[10]), atoi(row[8]), atoi(row[9]), atoi(row[7]));
|
||||
NPCType tempNPCStruct = Bot::FillNPCTypeStruct(
|
||||
auto defaultNPCTypeStruct = Bot::CreateDefaultNPCTypeStructForBot(std::string(row[2]), std::string(row[3]), atoi(row[10]), atoi(row[8]), atoi(row[9]), atoi(row[7]));
|
||||
auto tempNPCStruct = Bot::FillNPCTypeStruct(
|
||||
atoi(row[1]),
|
||||
std::string(row[2]),
|
||||
std::string(row[3]),
|
||||
@@ -379,21 +344,21 @@ bool BotDatabase::LoadBot(const uint32 bot_id, Bot*& loaded_bot)
|
||||
atoi(row[25]),
|
||||
atoi(row[28]),
|
||||
atoi(row[29]),
|
||||
defaultNPCTypeStruct.MR,
|
||||
defaultNPCTypeStruct.CR,
|
||||
defaultNPCTypeStruct.DR,
|
||||
defaultNPCTypeStruct.FR,
|
||||
defaultNPCTypeStruct.PR,
|
||||
defaultNPCTypeStruct.Corrup,
|
||||
defaultNPCTypeStruct.AC,
|
||||
defaultNPCTypeStruct.STR,
|
||||
defaultNPCTypeStruct.STA,
|
||||
defaultNPCTypeStruct.DEX,
|
||||
defaultNPCTypeStruct.AGI,
|
||||
defaultNPCTypeStruct.INT,
|
||||
defaultNPCTypeStruct.WIS,
|
||||
defaultNPCTypeStruct.CHA,
|
||||
defaultNPCTypeStruct.ATK
|
||||
defaultNPCTypeStruct->MR,
|
||||
defaultNPCTypeStruct->CR,
|
||||
defaultNPCTypeStruct->DR,
|
||||
defaultNPCTypeStruct->FR,
|
||||
defaultNPCTypeStruct->PR,
|
||||
defaultNPCTypeStruct->Corrup,
|
||||
defaultNPCTypeStruct->AC,
|
||||
defaultNPCTypeStruct->STR,
|
||||
defaultNPCTypeStruct->STA,
|
||||
defaultNPCTypeStruct->DEX,
|
||||
defaultNPCTypeStruct->AGI,
|
||||
defaultNPCTypeStruct->INT,
|
||||
defaultNPCTypeStruct->WIS,
|
||||
defaultNPCTypeStruct->CHA,
|
||||
defaultNPCTypeStruct->ATK
|
||||
);
|
||||
|
||||
loaded_bot = new Bot(bot_id, atoi(row[0]), atoi(row[1]), atof(row[14]), atoi(row[6]), tempNPCStruct);
|
||||
@@ -550,7 +515,7 @@ bool BotDatabase::SaveNewBot(Bot* bot_inst, uint32& bot_id)
|
||||
BOT_FOLLOW_DISTANCE_DEFAULT,
|
||||
(IsCasterClass(bot_inst->GetClass()) ? (uint8)RuleI(Bots, CasterStopMeleeLevel) : 255)
|
||||
);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
|
||||
@@ -653,7 +618,7 @@ bool BotDatabase::SaveBot(Bot* bot_inst)
|
||||
bot_inst->GetStopMeleeLevel(),
|
||||
bot_inst->GetBotID()
|
||||
);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
|
||||
@@ -666,7 +631,7 @@ bool BotDatabase::DeleteBot(const uint32 bot_id)
|
||||
return false;
|
||||
|
||||
query = StringFormat("DELETE FROM `bot_data` WHERE `bot_id` = '%u'", bot_id);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
|
||||
@@ -702,7 +667,7 @@ bool BotDatabase::LoadBuffs(Bot* bot_inst)
|
||||
" WHERE `bot_id` = '%u'",
|
||||
bot_inst->GetBotID()
|
||||
);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
if (!results.RowCount())
|
||||
@@ -821,7 +786,7 @@ bool BotDatabase::SaveBuffs(Bot* bot_inst)
|
||||
bot_buffs[buff_index].caston_z,
|
||||
bot_buffs[buff_index].ExtraDIChance
|
||||
);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
DeleteBuffs(bot_inst->GetBotID());
|
||||
return false;
|
||||
@@ -837,7 +802,7 @@ bool BotDatabase::DeleteBuffs(const uint32 bot_id)
|
||||
return false;
|
||||
|
||||
query = StringFormat("DELETE FROM `bot_buffs` WHERE `bot_id` = '%u'", bot_id);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
|
||||
@@ -850,7 +815,7 @@ bool BotDatabase::LoadStance(const uint32 bot_id, int& bot_stance)
|
||||
return false;
|
||||
|
||||
query = StringFormat("SELECT `stance_id` FROM `bot_stances` WHERE `bot_id` = '%u' LIMIT 1", bot_id);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
if (!results.RowCount())
|
||||
@@ -870,14 +835,14 @@ bool BotDatabase::LoadStance(Bot* bot_inst, bool& stance_flag)
|
||||
bot_inst->SetDefaultBotStance();
|
||||
|
||||
query = StringFormat("SELECT `stance_id` FROM `bot_stances` WHERE `bot_id` = '%u' LIMIT 1", bot_inst->GetBotID());
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
if (!results.RowCount())
|
||||
return true;
|
||||
|
||||
auto row = results.begin();
|
||||
bot_inst->SetBotStance((BotStanceType)atoi(row[0]));
|
||||
bot_inst->SetBotStance((EQEmu::constants::StanceType)atoi(row[0]));
|
||||
stance_flag = true;
|
||||
|
||||
return true;
|
||||
@@ -892,7 +857,7 @@ bool BotDatabase::SaveStance(const uint32 bot_id, const int bot_stance)
|
||||
return false;
|
||||
|
||||
query = StringFormat("INSERT INTO `bot_stances` (`bot_id`, `stance_id`) VALUES ('%u', '%u')", bot_id, bot_stance);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
DeleteStance(bot_id);
|
||||
return false;
|
||||
@@ -910,7 +875,7 @@ bool BotDatabase::SaveStance(Bot* bot_inst)
|
||||
return false;
|
||||
|
||||
query = StringFormat("INSERT INTO `bot_stances` (`bot_id`, `stance_id`) VALUES ('%u', '%u')", bot_inst->GetBotID(), bot_inst->GetBotStance());
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
DeleteStance(bot_inst->GetBotID());
|
||||
return false;
|
||||
@@ -925,7 +890,7 @@ bool BotDatabase::DeleteStance(const uint32 bot_id)
|
||||
return false;
|
||||
|
||||
query = StringFormat("DELETE FROM `bot_stances` WHERE `bot_id` = '%u'", bot_id);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
|
||||
@@ -956,7 +921,7 @@ bool BotDatabase::LoadTimers(Bot* bot_inst)
|
||||
bot_inst->GetClass(),
|
||||
bot_inst->GetLevel()
|
||||
);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
if (!results.RowCount())
|
||||
@@ -998,7 +963,7 @@ bool BotDatabase::SaveTimers(Bot* bot_inst)
|
||||
continue;
|
||||
|
||||
query = StringFormat("INSERT INTO `bot_timers` (`bot_id`, `timer_id`, `timer_value`) VALUES ('%u', '%u', '%u')", bot_inst->GetBotID(), (timer_index + 1), bot_timers[timer_index]);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
DeleteTimers(bot_inst->GetBotID());
|
||||
return false;
|
||||
@@ -1014,7 +979,7 @@ bool BotDatabase::DeleteTimers(const uint32 bot_id)
|
||||
return false;
|
||||
|
||||
query = StringFormat("DELETE FROM `bot_timers` WHERE `bot_id` = '%u'", bot_id);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
|
||||
@@ -1039,7 +1004,7 @@ bool BotDatabase::LoadGuildMembership(const uint32 bot_id, uint32& guild_id, uin
|
||||
" LIMIT 1",
|
||||
bot_id
|
||||
);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
if (!results.RowCount())
|
||||
@@ -1062,7 +1027,7 @@ bool BotDatabase::SaveGuildMembership(const uint32 bot_id, const uint32 guild_id
|
||||
return false;
|
||||
|
||||
query = StringFormat("INSERT INTO `bot_guild_members` SET `bot_id` = '%u', `guild_id` = '%u', `rank` = '%u'", bot_id, guild_id, guild_rank);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
DeleteGuildMembership(bot_id);
|
||||
return false;
|
||||
@@ -1077,7 +1042,7 @@ bool BotDatabase::DeleteGuildMembership(const uint32 bot_id)
|
||||
return false;
|
||||
|
||||
query = StringFormat("DELETE FROM `bot_guild_members` WHERE `bot_id` = '%u'", bot_id);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
|
||||
@@ -1092,7 +1057,7 @@ bool BotDatabase::QueryInventoryCount(const uint32 bot_id, uint32& item_count)
|
||||
return false;
|
||||
|
||||
query = StringFormat("SELECT COUNT(`inventories_index`) FROM `bot_inventories` WHERE `bot_id` = '%u'", bot_id);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
if (!results.RowCount())
|
||||
@@ -1131,7 +1096,7 @@ bool BotDatabase::LoadItems(const uint32 bot_id, EQEmu::InventoryProfile& invent
|
||||
" ORDER BY `slot_id`",
|
||||
bot_id
|
||||
);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
if (!results.RowCount())
|
||||
@@ -1228,7 +1193,7 @@ bool BotDatabase::DeleteItems(const uint32 bot_id)
|
||||
return false;
|
||||
|
||||
query = StringFormat("DELETE FROM `bot_inventories` WHERE `bot_id` = '%u'", bot_id);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
|
||||
@@ -1246,7 +1211,7 @@ bool BotDatabase::LoadItemBySlot(const uint32 bot_id, const uint32 slot_id, uint
|
||||
return false;
|
||||
|
||||
query = StringFormat("SELECT `item_id` FROM `bot_inventories` WHERE `bot_id` = '%i' AND `slot_id` = '%i' LIMIT 1", bot_id, slot_id);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
if (!results.RowCount())
|
||||
@@ -1333,7 +1298,7 @@ bool BotDatabase::SaveItemBySlot(Bot* bot_inst, const uint32 slot_id, const EQEm
|
||||
(unsigned long)augment_id[4],
|
||||
(unsigned long)augment_id[5]
|
||||
);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
DeleteItemBySlot(bot_inst->GetBotID(), slot_id);
|
||||
return false;
|
||||
@@ -1348,7 +1313,7 @@ bool BotDatabase::DeleteItemBySlot(const uint32 bot_id, const uint32 slot_id)
|
||||
return false;
|
||||
|
||||
query = StringFormat("DELETE FROM `bot_inventories` WHERE `bot_id` = '%u' AND `slot_id` = '%u'", bot_id, slot_id);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
|
||||
@@ -1365,7 +1330,7 @@ bool BotDatabase::LoadEquipmentColor(const uint32 bot_id, const uint8 material_s
|
||||
return false;
|
||||
|
||||
query = StringFormat("SELECT `inst_color` FROM `bot_inventories` WHERE `bot_id` = '%u' AND `slot_id` = '%u' LIMIT 1", bot_id, slot_id);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
if (!results.RowCount())
|
||||
@@ -1401,7 +1366,7 @@ bool BotDatabase::SaveEquipmentColor(const uint32 bot_id, const int16 slot_id, c
|
||||
bot_id,
|
||||
where_clause.c_str()
|
||||
);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
|
||||
@@ -1416,7 +1381,7 @@ bool BotDatabase::LoadPetIndex(const uint32 bot_id, uint32& pet_index)
|
||||
return false;
|
||||
|
||||
query = StringFormat("SELECT `pets_index` FROM `bot_pets` WHERE `bot_id` = '%u' LIMIT 1", bot_id);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
if (!results.RowCount())
|
||||
@@ -1434,7 +1399,7 @@ bool BotDatabase::LoadPetSpellID(const uint32 bot_id, uint32& pet_spell_id)
|
||||
return false;
|
||||
|
||||
query = StringFormat("SELECT `spell_id` FROM `bot_pets` WHERE `bot_id` = '%u' LIMIT 1", bot_id);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
if (!results.RowCount())
|
||||
@@ -1458,7 +1423,7 @@ bool BotDatabase::LoadPetStats(const uint32 bot_id, std::string& pet_name, uint3
|
||||
return true;
|
||||
|
||||
query = StringFormat("SELECT `spell_id`, `name`, `mana`, `hp` FROM `bot_pets` WHERE `pets_index` = '%u' LIMIT 1", saved_pet_index);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
if (!results.RowCount())
|
||||
@@ -1506,7 +1471,7 @@ bool BotDatabase::SavePetStats(const uint32 bot_id, const std::string& pet_name,
|
||||
pet_mana,
|
||||
pet_hp
|
||||
);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
DeletePetStats(bot_id);
|
||||
return false;
|
||||
@@ -1527,7 +1492,7 @@ bool BotDatabase::DeletePetStats(const uint32 bot_id)
|
||||
return true;
|
||||
|
||||
query = StringFormat("DELETE FROM `bot_pets` WHERE `pets_index` = '%u'", saved_pet_index);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
|
||||
@@ -1546,7 +1511,7 @@ bool BotDatabase::LoadPetBuffs(const uint32 bot_id, SpellBuff_Struct* pet_buffs)
|
||||
return true;
|
||||
|
||||
query = StringFormat("SELECT `spell_id`, `caster_level`, `duration` FROM `bot_pet_buffs` WHERE `pets_index` = '%u'", saved_pet_index);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
if (!results.RowCount())
|
||||
@@ -1612,7 +1577,7 @@ bool BotDatabase::SavePetBuffs(const uint32 bot_id, const SpellBuff_Struct* pet_
|
||||
pet_buffs[buff_index].level,
|
||||
pet_buffs[buff_index].duration
|
||||
);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
DeletePetBuffs(bot_id);
|
||||
return false;
|
||||
@@ -1634,7 +1599,7 @@ bool BotDatabase::DeletePetBuffs(const uint32 bot_id)
|
||||
return true;
|
||||
|
||||
query = StringFormat("DELETE FROM `bot_pet_buffs` WHERE `pets_index` = '%u'", saved_pet_index);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
|
||||
@@ -1653,7 +1618,7 @@ bool BotDatabase::LoadPetItems(const uint32 bot_id, uint32* pet_items)
|
||||
return true;
|
||||
|
||||
query = StringFormat("SELECT `item_id` FROM `bot_pet_inventories` WHERE `pets_index` = '%u'", saved_pet_index);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
if (!results.RowCount())
|
||||
@@ -1689,7 +1654,7 @@ bool BotDatabase::SavePetItems(const uint32 bot_id, const uint32* pet_items, boo
|
||||
continue;
|
||||
|
||||
query = StringFormat("INSERT INTO `bot_pet_inventories` (`pets_index`, `item_id`) VALUES ('%u', '%u')", saved_pet_index, pet_items[item_index]);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
DeletePetItems(bot_id);
|
||||
return false;
|
||||
@@ -1711,7 +1676,7 @@ bool BotDatabase::DeletePetItems(const uint32 bot_id)
|
||||
return true;
|
||||
|
||||
query = StringFormat("DELETE FROM `bot_pet_inventories` WHERE `pets_index` = '%u'", saved_pet_index);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
|
||||
@@ -1726,7 +1691,7 @@ bool BotDatabase::LoadInspectMessage(const uint32 bot_id, InspectMessage_Struct&
|
||||
return false;
|
||||
|
||||
query = StringFormat("SELECT `inspect_message` FROM `bot_inspect_messages` WHERE `bot_id` = '%u' LIMIT 1", bot_id);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
if (!results.RowCount())
|
||||
@@ -1759,7 +1724,7 @@ bool BotDatabase::SaveInspectMessage(const uint32 bot_id, const InspectMessage_S
|
||||
return true;
|
||||
|
||||
query = StringFormat("INSERT INTO `bot_inspect_messages` (`bot_id`, `inspect_message`) VALUES ('%u', '%s')", bot_id, bot_message.c_str());
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
DeleteInspectMessage(bot_id);
|
||||
return false;
|
||||
@@ -1774,7 +1739,7 @@ bool BotDatabase::DeleteInspectMessage(const uint32 bot_id)
|
||||
return false;
|
||||
|
||||
query = StringFormat("DELETE FROM `bot_inspect_messages` WHERE `bot_id` = '%u'", bot_id);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
|
||||
@@ -1796,7 +1761,7 @@ bool BotDatabase::SaveAllInspectMessages(const uint32 owner_id, const InspectMes
|
||||
return true;
|
||||
|
||||
query = StringFormat("INSERT INTO `bot_inspect_messages` (`bot_id`, `inspect_message`) SELECT `bot_id`, '%s' inspect_message FROM `bot_data` WHERE `owner_id` = '%u'", bot_message.c_str(), owner_id);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
DeleteAllInspectMessages(owner_id);
|
||||
return false;
|
||||
@@ -1811,7 +1776,7 @@ bool BotDatabase::DeleteAllInspectMessages(const uint32 owner_id)
|
||||
return false;
|
||||
|
||||
query = StringFormat("DELETE FROM `bot_inspect_messages` WHERE `bot_id` IN (SELECT `bot_id` FROM `bot_data` WHERE `owner_id` = '%u')", owner_id);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
|
||||
@@ -1836,7 +1801,7 @@ bool BotDatabase::SaveAllArmorColorBySlot(const uint32 owner_id, const int16 slo
|
||||
EQEmu::invslot::slotHead, EQEmu::invslot::slotChest, EQEmu::invslot::slotArms, EQEmu::invslot::slotWrist1, EQEmu::invslot::slotWrist2, EQEmu::invslot::slotHands, EQEmu::invslot::slotLegs, EQEmu::invslot::slotFeet,
|
||||
slot_id
|
||||
);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
|
||||
@@ -1859,7 +1824,7 @@ bool BotDatabase::SaveAllArmorColors(const uint32 owner_id, const uint32 rgb_val
|
||||
rgb_value,
|
||||
EQEmu::invslot::slotHead, EQEmu::invslot::slotChest, EQEmu::invslot::slotArms, EQEmu::invslot::slotWrist1, EQEmu::invslot::slotWrist2, EQEmu::invslot::slotHands, EQEmu::invslot::slotLegs, EQEmu::invslot::slotFeet
|
||||
);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
|
||||
@@ -1880,7 +1845,7 @@ bool BotDatabase::SaveHelmAppearance(const uint32 owner_id, const uint32 bot_id,
|
||||
owner_id,
|
||||
bot_id
|
||||
);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
|
||||
@@ -1899,7 +1864,7 @@ bool BotDatabase::SaveAllHelmAppearances(const uint32 owner_id, const bool show_
|
||||
(show_flag ? 1 : 0),
|
||||
owner_id
|
||||
);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
|
||||
@@ -1919,7 +1884,7 @@ bool BotDatabase::ToggleHelmAppearance(const uint32 owner_id, const uint32 bot_i
|
||||
owner_id,
|
||||
bot_id
|
||||
);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
|
||||
@@ -1937,7 +1902,7 @@ bool BotDatabase::ToggleAllHelmAppearances(const uint32 owner_id)
|
||||
" WHERE `owner_id` = '%u'",
|
||||
owner_id
|
||||
);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
|
||||
@@ -1958,7 +1923,7 @@ bool BotDatabase::SaveFollowDistance(const uint32 owner_id, const uint32 bot_id,
|
||||
owner_id,
|
||||
bot_id
|
||||
);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
|
||||
@@ -1977,7 +1942,7 @@ bool BotDatabase::SaveAllFollowDistances(const uint32 owner_id, const uint32 fol
|
||||
follow_distance,
|
||||
owner_id
|
||||
);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
|
||||
@@ -2095,7 +2060,7 @@ bool BotDatabase::CreateCloneBot(const uint32 owner_id, const uint32 bot_id, con
|
||||
owner_id,
|
||||
bot_id
|
||||
);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
|
||||
@@ -2156,7 +2121,7 @@ bool BotDatabase::CreateCloneBotInventory(const uint32 owner_id, const uint32 bo
|
||||
owner_id,
|
||||
bot_id
|
||||
);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
DeleteItems(clone_id);
|
||||
return false;
|
||||
@@ -2179,7 +2144,7 @@ bool BotDatabase::SaveStopMeleeLevel(const uint32 owner_id, const uint32 bot_id,
|
||||
owner_id,
|
||||
bot_id
|
||||
);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
|
||||
@@ -2192,22 +2157,23 @@ bool BotDatabase::LoadOwnerOptions(Client *owner)
|
||||
return false;
|
||||
|
||||
query = StringFormat(
|
||||
"SELECT `death_marquee` FROM `bot_owner_options`"
|
||||
"SELECT `death_marquee`, `stats_update` FROM `bot_owner_options`"
|
||||
" WHERE `owner_id` = '%u'",
|
||||
owner->CharacterID()
|
||||
);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
if (!results.RowCount()) {
|
||||
query = StringFormat("REPLACE INTO `bot_owner_options` (`owner_id`) VALUES ('%u')", owner->CharacterID());
|
||||
results = QueryDatabase(query);
|
||||
results = database.QueryDatabase(query);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
auto row = results.begin();
|
||||
owner->SetBotOptionDeathMarquee((atoi(row[0]) != 0));
|
||||
owner->SetBotOptionStatsUpdate((atoi(row[1]) != 0));
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -2224,7 +2190,26 @@ bool BotDatabase::SaveOwnerOptionDeathMarquee(const uint32 owner_id, const bool
|
||||
(flag == true ? 1 : 0),
|
||||
owner_id
|
||||
);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BotDatabase::SaveOwnerOptionStatsUpdate(const uint32 owner_id, const bool flag)
|
||||
{
|
||||
if (!owner_id)
|
||||
return false;
|
||||
|
||||
query = StringFormat(
|
||||
"UPDATE `bot_owner_options`"
|
||||
" SET `stats_update` = '%u'"
|
||||
" WHERE `owner_id` = '%u'",
|
||||
(flag == true ? 1 : 0),
|
||||
owner_id
|
||||
);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
|
||||
@@ -2239,7 +2224,7 @@ bool BotDatabase::QueryBotGroupExistence(const std::string& group_name, bool& ex
|
||||
return false;
|
||||
|
||||
query = StringFormat("SELECT `group_name` FROM `vw_bot_groups` WHERE `group_name` LIKE '%s' LIMIT 1", group_name.c_str());
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
if (!results.RowCount())
|
||||
@@ -2256,7 +2241,7 @@ bool BotDatabase::LoadBotGroupIDByBotGroupName(const std::string& group_name, ui
|
||||
return false;
|
||||
|
||||
query = StringFormat("SELECT `groups_index` FROM `bot_groups` WHERE `group_name` = '%s' LIMIT 1", group_name.c_str());
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
if (!results.RowCount())
|
||||
@@ -2274,7 +2259,7 @@ bool BotDatabase::LoadBotGroupIDByLeaderID(const uint32 leader_id, uint32& botgr
|
||||
return false;
|
||||
|
||||
query = StringFormat("SELECT `groups_index` FROM `bot_groups` WHERE `group_leader_id` = '%u' LIMIT 1", leader_id);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
if (!results.RowCount())
|
||||
@@ -2292,7 +2277,7 @@ bool BotDatabase::LoadBotGroupIDByMemberID(const uint32 member_id, uint32& botgr
|
||||
return false;
|
||||
|
||||
query = StringFormat("SELECT `groups_index` FROM `bot_group_members` WHERE `bot_id` = '%u' LIMIT 1", member_id);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
if (!results.RowCount())
|
||||
@@ -2310,7 +2295,7 @@ bool BotDatabase::LoadLeaderIDByBotGroupName(const std::string& group_name, uint
|
||||
return false;
|
||||
|
||||
query = StringFormat("SELECT `group_leader_id` FROM `bot_groups` WHERE `group_name` = '%s' LIMIT 1", group_name.c_str());
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
if (!results.RowCount())
|
||||
@@ -2328,7 +2313,7 @@ bool BotDatabase::LoadLeaderIDByBotGroupID(const uint32 group_id, uint32& leader
|
||||
return false;
|
||||
|
||||
query = StringFormat("SELECT `group_leader_id` FROM `bot_groups` WHERE `groups_index` = '%u' LIMIT 1", group_id);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
if (!results.RowCount())
|
||||
@@ -2346,7 +2331,7 @@ bool BotDatabase::LoadBotGroupNameByBotGroupID(const uint32 group_id, std::strin
|
||||
false;
|
||||
|
||||
query = StringFormat("SELECT `group_name` FROM `bot_groups` WHERE `groups_index` = '%u' LIMIT 1", group_id);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
if (!results.RowCount())
|
||||
@@ -2364,7 +2349,7 @@ bool BotDatabase::LoadBotGroupNameByLeaderID(const uint32 leader_id, std::string
|
||||
return false;
|
||||
|
||||
query = StringFormat("SELECT `group_name` FROM `bot_groups` WHERE `group_leader_id` = '%u' LIMIT 1", leader_id);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
if (!results.RowCount())
|
||||
@@ -2388,7 +2373,7 @@ bool BotDatabase::CreateBotGroup(const std::string& group_name, const uint32 lea
|
||||
return true;
|
||||
|
||||
query = StringFormat("INSERT INTO `bot_groups` (`group_leader_id`, `group_name`) VALUES ('%u', '%s')", leader_id, group_name.c_str());
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
DeleteBotGroup(leader_id);
|
||||
return false;
|
||||
@@ -2401,7 +2386,7 @@ bool BotDatabase::CreateBotGroup(const std::string& group_name, const uint32 lea
|
||||
}
|
||||
|
||||
query = StringFormat("INSERT INTO `bot_group_members` (`groups_index`, `bot_id`) VALUES ('%u', '%u')", botgroup_id, leader_id);
|
||||
results = QueryDatabase(query);
|
||||
results = database.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
RemoveMemberFromBotGroup(leader_id);
|
||||
return false;
|
||||
@@ -2422,12 +2407,12 @@ bool BotDatabase::DeleteBotGroup(const uint32 leader_id)
|
||||
return true;
|
||||
|
||||
query = StringFormat("DELETE FROM `bot_group_members` WHERE `groups_index` = '%u'", botgroup_id);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
|
||||
query = StringFormat("DELETE FROM `bot_groups` WHERE `groups_index` = '%u'", botgroup_id);
|
||||
results = QueryDatabase(query);
|
||||
results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
|
||||
@@ -2446,7 +2431,7 @@ bool BotDatabase::AddMemberToBotGroup(const uint32 leader_id, const uint32 membe
|
||||
return true;
|
||||
|
||||
query = StringFormat("INSERT INTO `bot_group_members` (`groups_index`, `bot_id`) VALUES ('%u', '%u')", botgroup_id, member_id);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
RemoveMemberFromBotGroup(member_id);
|
||||
return false;
|
||||
@@ -2467,7 +2452,7 @@ bool BotDatabase::RemoveMemberFromBotGroup(const uint32 member_id)
|
||||
return DeleteBotGroup(member_id);
|
||||
|
||||
query = StringFormat("DELETE FROM `bot_group_members` WHERE `bot_id` = '%u'", member_id);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
|
||||
@@ -2480,7 +2465,7 @@ bool BotDatabase::LoadBotGroupIDForLoadBotGroup(const uint32 owner_id, const std
|
||||
return false;
|
||||
|
||||
query = StringFormat("SELECT `groups_index`, `group_name` FROM `vw_bot_groups` WHERE `owner_id` = '%u'", owner_id);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
if (!results.RowCount())
|
||||
@@ -2508,7 +2493,7 @@ bool BotDatabase::LoadBotGroup(const std::string& group_name, std::map<uint32, s
|
||||
return true;
|
||||
|
||||
query = StringFormat("SELECT `bot_id` FROM `bot_group_members` WHERE `groups_index` = '%u' LIMIT 6", botgroup_id);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
if (!results.RowCount())
|
||||
@@ -2526,7 +2511,7 @@ bool BotDatabase::LoadBotGroupsListByOwnerID(const uint32 owner_id, std::list<st
|
||||
return false;
|
||||
|
||||
query = StringFormat("SELECT `group_name`, `group_leader_name` FROM `vw_bot_groups` WHERE `owner_id` = '%u'", owner_id);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
if (!results.RowCount())
|
||||
@@ -2559,7 +2544,7 @@ bool BotDatabase::LoadGroupedBotsByGroupID(const uint32 owner_id, const uint32 g
|
||||
owner_id
|
||||
);
|
||||
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
if (!results.RowCount())
|
||||
@@ -2579,7 +2564,7 @@ bool BotDatabase::LoadHealRotationIDByBotID(const uint32 bot_id, uint32& hr_inde
|
||||
return false;
|
||||
|
||||
query = StringFormat("SELECT `heal_rotation_index` FROM `bot_heal_rotations` WHERE `bot_id` = '%u' LIMIT 1", bot_id);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
if (!results.RowCount())
|
||||
@@ -2626,7 +2611,7 @@ bool BotDatabase::LoadHealRotation(Bot* hr_member, std::list<uint32>& member_lis
|
||||
" LIMIT 1",
|
||||
hr_index
|
||||
);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
if (!results.RowCount())
|
||||
@@ -2665,7 +2650,7 @@ bool BotDatabase::LoadHealRotationMembers(const uint32 hr_index, std::list<uint3
|
||||
return false;
|
||||
|
||||
query = StringFormat("SELECT `bot_id` FROM `bot_heal_rotation_members` WHERE `heal_rotation_index` = '%u'", hr_index);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
if (!results.RowCount())
|
||||
@@ -2685,7 +2670,7 @@ bool BotDatabase::LoadHealRotationTargets(const uint32 hr_index, std::list<std::
|
||||
return false;
|
||||
|
||||
query = StringFormat("SELECT `target_name` FROM `bot_heal_rotation_targets` WHERE `heal_rotation_index` = '%u'", hr_index);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
if (!results.RowCount())
|
||||
@@ -2761,7 +2746,7 @@ bool BotDatabase::SaveHealRotation(Bot* hr_member, bool& member_fail, bool& targ
|
||||
((*hr_member->MemberOfHealRotation())->ArmorTypeCriticalHPRatio(ARMOR_TYPE_CHAIN)),
|
||||
((*hr_member->MemberOfHealRotation())->ArmorTypeCriticalHPRatio(ARMOR_TYPE_PLATE))
|
||||
);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
|
||||
@@ -2776,7 +2761,7 @@ bool BotDatabase::SaveHealRotation(Bot* hr_member, bool& member_fail, bool& targ
|
||||
continue;
|
||||
|
||||
query = StringFormat("INSERT INTO `bot_heal_rotation_members` (`heal_rotation_index`, `bot_id`) VALUES ('%u', '%u')", hr_index, member_iter->GetBotID());
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
member_fail = true;
|
||||
break;
|
||||
@@ -2790,7 +2775,7 @@ bool BotDatabase::SaveHealRotation(Bot* hr_member, bool& member_fail, bool& targ
|
||||
continue;
|
||||
|
||||
query = StringFormat("INSERT INTO `bot_heal_rotation_targets` (`heal_rotation_index`, `target_name`) VALUES ('%u', '%s')", hr_index, target_iter->GetCleanName());
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
target_fail = true;
|
||||
break;
|
||||
@@ -2812,17 +2797,17 @@ bool BotDatabase::DeleteHealRotation(const uint32 creator_id)
|
||||
return true;
|
||||
|
||||
query = StringFormat("DELETE FROM `bot_heal_rotation_targets` WHERE `heal_rotation_index` = '%u'", hr_index);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
|
||||
query = StringFormat("DELETE FROM `bot_heal_rotation_members` WHERE `heal_rotation_index` = '%u'", hr_index);
|
||||
results = QueryDatabase(query);
|
||||
results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
|
||||
query = StringFormat("DELETE FROM `bot_heal_rotations` WHERE `heal_rotation_index` = '%u'", hr_index);
|
||||
results = QueryDatabase(query);
|
||||
results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
|
||||
@@ -2835,7 +2820,7 @@ bool BotDatabase::DeleteAllHealRotations(const uint32 owner_id)
|
||||
return false;
|
||||
|
||||
query = StringFormat("SELECT `bot_id` FROM `bot_heal_rotations` WHERE `bot_id` IN (SELECT `bot_id` FROM `bot_data` WHERE `owner_id` = '%u')", owner_id);
|
||||
auto results = QueryDatabase(query);
|
||||
auto results = database.QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
|
||||
@@ -2853,16 +2838,16 @@ bool BotDatabase::DeleteAllHealRotations(const uint32 owner_id)
|
||||
/* Bot miscellaneous functions */
|
||||
uint8 BotDatabase::GetSpellCastingChance(uint8 spell_type_index, uint8 class_index, uint8 stance_index, uint8 conditional_index) // class_index is 0-based
|
||||
{
|
||||
if (spell_type_index >= MaxSpellTypes)
|
||||
if (spell_type_index >= Bot::SPELL_TYPE_COUNT)
|
||||
return 0;
|
||||
if (class_index >= PLAYER_CLASS_COUNT)
|
||||
return 0;
|
||||
if (stance_index >= MaxStances)
|
||||
if (stance_index >= EQEmu::constants::STANCE_TYPE_COUNT)
|
||||
return 0;
|
||||
if (conditional_index >= cntHSND)
|
||||
return 0;
|
||||
|
||||
return spell_casting_chances[spell_type_index][class_index][stance_index][conditional_index];
|
||||
return Bot::spell_casting_chances[spell_type_index][class_index][stance_index][conditional_index];
|
||||
}
|
||||
|
||||
|
||||
|
||||
+4
-13
@@ -22,17 +22,15 @@
|
||||
|
||||
#ifdef BOTS
|
||||
|
||||
#include "../common/dbcore.h"
|
||||
#include "../common/eq_packet_structs.h"
|
||||
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
|
||||
class Bot;
|
||||
struct BotsAvailableList;
|
||||
class Client;
|
||||
struct BotsAvailableList;
|
||||
struct InspectMessage_Struct;
|
||||
|
||||
namespace EQEmu
|
||||
{
|
||||
@@ -41,15 +39,9 @@ namespace EQEmu
|
||||
}
|
||||
|
||||
|
||||
class BotDatabase : public DBcore
|
||||
class BotDatabase
|
||||
{
|
||||
public:
|
||||
BotDatabase();
|
||||
BotDatabase(const char* host, const char* user, const char* passwd, const char* database, uint32 port);
|
||||
virtual ~BotDatabase();
|
||||
|
||||
bool Connect(const char* host, const char* user, const char* passwd, const char* database, uint32 port);
|
||||
|
||||
bool LoadBotCommandSettings(std::map<std::string, std::pair<uint8, std::vector<std::string>>> &bot_command_settings);
|
||||
bool LoadBotSpellCastingChances();
|
||||
|
||||
@@ -148,6 +140,7 @@ public:
|
||||
|
||||
bool LoadOwnerOptions(Client *owner);
|
||||
bool SaveOwnerOptionDeathMarquee(const uint32 owner_id, const bool flag);
|
||||
bool SaveOwnerOptionStatsUpdate(const uint32 owner_id, const bool flag);
|
||||
|
||||
/* Bot bot-group functions */
|
||||
bool QueryBotGroupExistence(const std::string& botgroup_name, bool& extant_flag);
|
||||
@@ -296,8 +289,6 @@ public:
|
||||
std::string query;
|
||||
};
|
||||
|
||||
extern BotDatabase botdb;
|
||||
|
||||
#endif
|
||||
|
||||
#endif // BOTS
|
||||
|
||||
+83
-84
@@ -192,25 +192,24 @@ bool Bot::AICastSpell(Mob* tar, uint8 iChance, uint32 iSpellTypes) {
|
||||
else {
|
||||
float hpRatioToCast = 0.0f;
|
||||
|
||||
switch(this->GetBotStance())
|
||||
{
|
||||
case BotStanceEfficient:
|
||||
case BotStanceAggressive:
|
||||
hpRatioToCast = isPrimaryHealer?90.0f:50.0f;
|
||||
break;
|
||||
case BotStanceBalanced:
|
||||
hpRatioToCast = isPrimaryHealer?95.0f:75.0f;
|
||||
break;
|
||||
case BotStanceReactive:
|
||||
hpRatioToCast = isPrimaryHealer?100.0f:90.0f;
|
||||
break;
|
||||
case BotStanceBurn:
|
||||
case BotStanceBurnAE:
|
||||
hpRatioToCast = isPrimaryHealer?75.0f:25.0f;
|
||||
break;
|
||||
default:
|
||||
hpRatioToCast = isPrimaryHealer?100.0f:0.0f;
|
||||
break;
|
||||
switch(this->GetBotStance()) {
|
||||
case EQEmu::constants::stanceEfficient:
|
||||
case EQEmu::constants::stanceAggressive:
|
||||
hpRatioToCast = isPrimaryHealer?90.0f:50.0f;
|
||||
break;
|
||||
case EQEmu::constants::stanceBalanced:
|
||||
hpRatioToCast = isPrimaryHealer?95.0f:75.0f;
|
||||
break;
|
||||
case EQEmu::constants::stanceReactive:
|
||||
hpRatioToCast = isPrimaryHealer?100.0f:90.0f;
|
||||
break;
|
||||
case EQEmu::constants::stanceBurn:
|
||||
case EQEmu::constants::stanceBurnAE:
|
||||
hpRatioToCast = isPrimaryHealer?75.0f:25.0f;
|
||||
break;
|
||||
default:
|
||||
hpRatioToCast = isPrimaryHealer?100.0f:0.0f;
|
||||
break;
|
||||
}
|
||||
|
||||
//If we're at specified mana % or below, don't heal as hybrid
|
||||
@@ -381,23 +380,22 @@ bool Bot::AICastSpell(Mob* tar, uint8 iChance, uint32 iSpellTypes) {
|
||||
{
|
||||
float manaRatioToCast = 75.0f;
|
||||
|
||||
switch(this->GetBotStance())
|
||||
{
|
||||
case BotStanceEfficient:
|
||||
manaRatioToCast = 90.0f;
|
||||
break;
|
||||
case BotStanceBalanced:
|
||||
case BotStanceAggressive:
|
||||
manaRatioToCast = 75.0f;
|
||||
break;
|
||||
case BotStanceReactive:
|
||||
case BotStanceBurn:
|
||||
case BotStanceBurnAE:
|
||||
manaRatioToCast = 50.0f;
|
||||
break;
|
||||
default:
|
||||
manaRatioToCast = 75.0f;
|
||||
break;
|
||||
switch(this->GetBotStance()) {
|
||||
case EQEmu::constants::stanceEfficient:
|
||||
manaRatioToCast = 90.0f;
|
||||
break;
|
||||
case EQEmu::constants::stanceBalanced:
|
||||
case EQEmu::constants::stanceAggressive:
|
||||
manaRatioToCast = 75.0f;
|
||||
break;
|
||||
case EQEmu::constants::stanceReactive:
|
||||
case EQEmu::constants::stanceBurn:
|
||||
case EQEmu::constants::stanceBurnAE:
|
||||
manaRatioToCast = 50.0f;
|
||||
break;
|
||||
default:
|
||||
manaRatioToCast = 75.0f;
|
||||
break;
|
||||
}
|
||||
|
||||
//If we're at specified mana % or below, don't rune as enchanter
|
||||
@@ -461,25 +459,24 @@ bool Bot::AICastSpell(Mob* tar, uint8 iChance, uint32 iSpellTypes) {
|
||||
{
|
||||
float manaRatioToCast = 75.0f;
|
||||
|
||||
switch(this->GetBotStance())
|
||||
{
|
||||
case BotStanceEfficient:
|
||||
manaRatioToCast = 90.0f;
|
||||
break;
|
||||
case BotStanceBalanced:
|
||||
manaRatioToCast = 75.0f;
|
||||
break;
|
||||
case BotStanceReactive:
|
||||
case BotStanceAggressive:
|
||||
manaRatioToCast = 50.0f;
|
||||
break;
|
||||
case BotStanceBurn:
|
||||
case BotStanceBurnAE:
|
||||
manaRatioToCast = 25.0f;
|
||||
break;
|
||||
default:
|
||||
manaRatioToCast = 50.0f;
|
||||
break;
|
||||
switch(this->GetBotStance()) {
|
||||
case EQEmu::constants::stanceEfficient:
|
||||
manaRatioToCast = 90.0f;
|
||||
break;
|
||||
case EQEmu::constants::stanceBalanced:
|
||||
manaRatioToCast = 75.0f;
|
||||
break;
|
||||
case EQEmu::constants::stanceReactive:
|
||||
case EQEmu::constants::stanceAggressive:
|
||||
manaRatioToCast = 50.0f;
|
||||
break;
|
||||
case EQEmu::constants::stanceBurn:
|
||||
case EQEmu::constants::stanceBurnAE:
|
||||
manaRatioToCast = 25.0f;
|
||||
break;
|
||||
default:
|
||||
manaRatioToCast = 50.0f;
|
||||
break;
|
||||
}
|
||||
|
||||
//If we're at specified mana % or below, don't nuke as cleric or enchanter
|
||||
@@ -1310,7 +1307,7 @@ bool Bot::AI_EngagedCastCheck() {
|
||||
AIautocastspell_timer->Disable(); //prevent the timer from going off AGAIN while we are casting.
|
||||
|
||||
uint8 botClass = GetClass();
|
||||
BotStanceType botStance = GetBotStance();
|
||||
EQEmu::constants::StanceType botStance = GetBotStance();
|
||||
bool mayGetAggro = HasOrMayGetAggro();
|
||||
|
||||
Log(Logs::Detail, Logs::AI, "Engaged autocast check triggered (BOTS). Trying to cast healing spells then maybe offensive spells.");
|
||||
@@ -2573,79 +2570,79 @@ bool Bot::CheckDisciplineRecastTimers(Bot *caster, int timer_index) {
|
||||
|
||||
uint8 Bot::GetChanceToCastBySpellType(uint32 spellType)
|
||||
{
|
||||
uint8 spell_type_index = MaxSpellTypes;
|
||||
uint8 spell_type_index = SPELL_TYPE_COUNT;
|
||||
switch (spellType) {
|
||||
case SpellType_Nuke:
|
||||
spell_type_index = SpellType_NukeIndex;
|
||||
spell_type_index = spellTypeIndexNuke;
|
||||
break;
|
||||
case SpellType_Heal:
|
||||
spell_type_index = SpellType_HealIndex;
|
||||
spell_type_index = spellTypeIndexHeal;
|
||||
break;
|
||||
case SpellType_Root:
|
||||
spell_type_index = SpellType_RootIndex;
|
||||
spell_type_index = spellTypeIndexRoot;
|
||||
break;
|
||||
case SpellType_Buff:
|
||||
spell_type_index = SpellType_BuffIndex;
|
||||
spell_type_index = spellTypeIndexBuff;
|
||||
break;
|
||||
case SpellType_Escape:
|
||||
spell_type_index = SpellType_EscapeIndex;
|
||||
spell_type_index = spellTypeIndexEscape;
|
||||
break;
|
||||
case SpellType_Pet:
|
||||
spell_type_index = SpellType_PetIndex;
|
||||
spell_type_index = spellTypeIndexPet;
|
||||
break;
|
||||
case SpellType_Lifetap:
|
||||
spell_type_index = SpellType_LifetapIndex;
|
||||
spell_type_index = spellTypeIndexLifetap;
|
||||
break;
|
||||
case SpellType_Snare:
|
||||
spell_type_index = SpellType_SnareIndex;
|
||||
spell_type_index = spellTypeIndexSnare;
|
||||
break;
|
||||
case SpellType_DOT:
|
||||
spell_type_index = SpellType_DOTIndex;
|
||||
spell_type_index = spellTypeIndexDot;
|
||||
break;
|
||||
case SpellType_Dispel:
|
||||
spell_type_index = SpellType_DispelIndex;
|
||||
spell_type_index = spellTypeIndexDispel;
|
||||
break;
|
||||
case SpellType_InCombatBuff:
|
||||
spell_type_index = SpellType_InCombatBuffIndex;
|
||||
spell_type_index = spellTypeIndexInCombatBuff;
|
||||
break;
|
||||
case SpellType_Mez:
|
||||
spell_type_index = SpellType_MezIndex;
|
||||
spell_type_index = spellTypeIndexMez;
|
||||
break;
|
||||
case SpellType_Charm:
|
||||
spell_type_index = SpellType_CharmIndex;
|
||||
spell_type_index = spellTypeIndexCharm;
|
||||
break;
|
||||
case SpellType_Slow:
|
||||
spell_type_index = SpellType_SlowIndex;
|
||||
spell_type_index = spellTypeIndexSlow;
|
||||
break;
|
||||
case SpellType_Debuff:
|
||||
spell_type_index = SpellType_DebuffIndex;
|
||||
spell_type_index = spellTypeIndexDebuff;
|
||||
break;
|
||||
case SpellType_Cure:
|
||||
spell_type_index = SpellType_CureIndex;
|
||||
spell_type_index = spellTypeIndexCure;
|
||||
break;
|
||||
case SpellType_Resurrect:
|
||||
spell_type_index = SpellType_ResurrectIndex;
|
||||
spell_type_index = spellTypeIndexResurrect;
|
||||
break;
|
||||
case SpellType_HateRedux:
|
||||
spell_type_index = SpellType_HateReduxIndex;
|
||||
spell_type_index = spellTypeIndexHateRedux;
|
||||
break;
|
||||
case SpellType_InCombatBuffSong:
|
||||
spell_type_index = SpellType_InCombatBuffSongIndex;
|
||||
spell_type_index = spellTypeIndexInCombatBuffSong;
|
||||
break;
|
||||
case SpellType_OutOfCombatBuffSong:
|
||||
spell_type_index = SpellType_OutOfCombatBuffSongIndex;
|
||||
spell_type_index = spellTypeIndexOutOfCombatBuffSong;
|
||||
break;
|
||||
case SpellType_PreCombatBuff:
|
||||
spell_type_index = SpellType_PreCombatBuffIndex;
|
||||
spell_type_index = spellTypeIndexPreCombatBuff;
|
||||
break;
|
||||
case SpellType_PreCombatBuffSong:
|
||||
spell_type_index = SpellType_PreCombatBuffSongIndex;
|
||||
spell_type_index = spellTypeIndexPreCombatBuffSong;
|
||||
break;
|
||||
default:
|
||||
spell_type_index = MaxSpellTypes;
|
||||
spell_type_index = SPELL_TYPE_COUNT;
|
||||
break;
|
||||
}
|
||||
if (spell_type_index >= MaxSpellTypes)
|
||||
if (spell_type_index >= SPELL_TYPE_COUNT)
|
||||
return 0;
|
||||
|
||||
uint8 class_index = GetClass();
|
||||
@@ -2653,11 +2650,13 @@ uint8 Bot::GetChanceToCastBySpellType(uint32 spellType)
|
||||
return 0;
|
||||
--class_index;
|
||||
|
||||
uint8 stance_index = (uint8)GetBotStance();
|
||||
if (stance_index >= MaxStances)
|
||||
EQEmu::constants::StanceType stance_type = GetBotStance();
|
||||
if (stance_type < EQEmu::constants::stancePassive || stance_type > EQEmu::constants::stanceBurnAE)
|
||||
return 0;
|
||||
|
||||
uint8 stance_index = EQEmu::constants::ConvertStanceTypeToIndex(stance_type);
|
||||
uint8 type_index = nHSND;
|
||||
|
||||
if (HasGroup()) {
|
||||
if (IsGroupHealer()/* || IsRaidHealer()*/)
|
||||
type_index |= pH;
|
||||
@@ -2669,7 +2668,7 @@ uint8 Bot::GetChanceToCastBySpellType(uint32 spellType)
|
||||
type_index |= pD;
|
||||
}
|
||||
|
||||
return botdb.GetSpellCastingChance(spell_type_index, class_index, stance_index, type_index);
|
||||
return database.botdb.GetSpellCastingChance(spell_type_index, class_index, stance_index, type_index);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+41
-12
@@ -38,6 +38,7 @@ extern volatile bool RunLoops;
|
||||
#include "../common/rulesys.h"
|
||||
#include "../common/string_util.h"
|
||||
#include "../common/data_verification.h"
|
||||
#include "../common/profanity_manager.h"
|
||||
#include "data_bucket.h"
|
||||
#include "position.h"
|
||||
#include "net.h"
|
||||
@@ -118,6 +119,7 @@ Client::Client(EQStreamInterface* ieqs)
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
),
|
||||
hpupdate_timer(2000),
|
||||
@@ -895,6 +897,10 @@ void Client::ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_s
|
||||
language = 0; // No need for language when drunk
|
||||
}
|
||||
|
||||
// Censor the message
|
||||
if (EQEmu::ProfanityManager::IsCensorshipActive() && (chan_num != 8))
|
||||
EQEmu::ProfanityManager::RedactMessage(message);
|
||||
|
||||
switch(chan_num)
|
||||
{
|
||||
case 0: { /* Guild Chat */
|
||||
@@ -1092,6 +1098,9 @@ void Client::ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_s
|
||||
break;
|
||||
}
|
||||
|
||||
if (EQEmu::ProfanityManager::IsCensorshipActive())
|
||||
EQEmu::ProfanityManager::RedactMessage(message);
|
||||
|
||||
#ifdef BOTS
|
||||
if (message[0] == BOT_COMMAND_CHAR) {
|
||||
if (bot_command_dispatch(this, message) == -2) {
|
||||
@@ -2595,9 +2604,12 @@ uint16 Client::GetMaxSkillAfterSpecializationRules(EQEmu::skills::SkillType skil
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Result += spellbonuses.RaiseSkillCap[skillid] + itembonuses.RaiseSkillCap[skillid] + aabonuses.RaiseSkillCap[skillid];
|
||||
|
||||
if (skillid == EQEmu::skills::SkillType::SkillForage)
|
||||
Result += aabonuses.GrantForage;
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
@@ -2640,6 +2652,11 @@ bool Client::CheckAccess(int16 iDBLevel, int16 iDefaultLevel) {
|
||||
}
|
||||
|
||||
void Client::MemorizeSpell(uint32 slot,uint32 spellid,uint32 scribing){
|
||||
if (slot < 0 || slot >= EQEmu::spells::DynamicLookup(ClientVersion(), GetGM())->SpellbookSize)
|
||||
return;
|
||||
if ((spellid < 3 || spellid > EQEmu::spells::DynamicLookup(ClientVersion(), GetGM())->SpellIdMax) && spellid != 0xFFFFFFFF)
|
||||
return;
|
||||
|
||||
auto outapp = new EQApplicationPacket(OP_MemorizeSpell, sizeof(MemorizeSpell_Struct));
|
||||
MemorizeSpell_Struct* mss=(MemorizeSpell_Struct*)outapp->pBuffer;
|
||||
mss->scribing=scribing;
|
||||
@@ -3457,7 +3474,7 @@ float Client::CalcPriceMod(Mob* other, bool reverse)
|
||||
float chaformula = 0;
|
||||
if (other)
|
||||
{
|
||||
int factionlvl = GetFactionLevel(CharacterID(), other->CastToNPC()->GetNPCTypeID(), GetRace(), GetClass(), GetDeity(), other->CastToNPC()->GetPrimaryFaction(), other);
|
||||
int factionlvl = GetFactionLevel(CharacterID(), other->CastToNPC()->GetNPCTypeID(), GetFactionRace(), GetClass(), GetDeity(), other->CastToNPC()->GetPrimaryFaction(), other);
|
||||
if (factionlvl >= FACTION_APPREHENSIVE) // Apprehensive or worse.
|
||||
{
|
||||
if (GetCHA() > 103)
|
||||
@@ -5595,6 +5612,12 @@ void Client::SuspendMinion()
|
||||
{
|
||||
if(m_suspendedminion.SpellID > 0)
|
||||
{
|
||||
if (m_suspendedminion.SpellID >= SPDAT_RECORDS) {
|
||||
Message(13, "Invalid suspended minion spell id (%u).", m_suspendedminion.SpellID);
|
||||
memset(&m_suspendedminion, 0, sizeof(PetInfo));
|
||||
return;
|
||||
}
|
||||
|
||||
MakePoweredPet(m_suspendedminion.SpellID, spells[m_suspendedminion.SpellID].teleport_zone,
|
||||
m_suspendedminion.petpower, m_suspendedminion.Name, m_suspendedminion.size);
|
||||
|
||||
@@ -7692,7 +7715,7 @@ FACTION_VALUE Client::GetReverseFactionCon(Mob* iOther) {
|
||||
if (iOther->GetPrimaryFaction() == 0)
|
||||
return FACTION_INDIFFERENT;
|
||||
|
||||
return GetFactionLevel(CharacterID(), 0, GetRace(), GetClass(), GetDeity(), iOther->GetPrimaryFaction(), iOther);
|
||||
return GetFactionLevel(CharacterID(), 0, GetFactionRace(), GetClass(), GetDeity(), iOther->GetPrimaryFaction(), iOther);
|
||||
}
|
||||
|
||||
//o--------------------------------------------------------------
|
||||
@@ -7779,7 +7802,7 @@ void Client::SetFactionLevel(uint32 char_id, uint32 npc_id, uint8 char_class, ui
|
||||
// Find out starting faction for this faction
|
||||
// It needs to be used to adj max and min personal
|
||||
// The range is still the same, 1200-3000(4200), but adjusted for base
|
||||
database.GetFactionData(&fm, GetClass(), GetRace(), GetDeity(),
|
||||
database.GetFactionData(&fm, GetClass(), GetFactionRace(), GetDeity(),
|
||||
faction_id[i]);
|
||||
|
||||
if (quest)
|
||||
@@ -7796,9 +7819,9 @@ void Client::SetFactionLevel(uint32 char_id, uint32 npc_id, uint8 char_class, ui
|
||||
//
|
||||
// Adjust these values for cases where starting faction is below
|
||||
// min or above max by not allowing any earn in those directions.
|
||||
this_faction_min = MIN_PERSONAL_FACTION - fm.base;
|
||||
this_faction_min = fm.min - fm.base;
|
||||
this_faction_min = std::min(0, this_faction_min);
|
||||
this_faction_max = MAX_PERSONAL_FACTION - fm.base;
|
||||
this_faction_max = fm.max - fm.base;
|
||||
this_faction_max = std::max(0, this_faction_max);
|
||||
|
||||
// Get the characters current value with that faction
|
||||
@@ -7829,7 +7852,7 @@ void Client::SetFactionLevel2(uint32 char_id, int32 faction_id, uint8 char_class
|
||||
// Find out starting faction for this faction
|
||||
// It needs to be used to adj max and min personal
|
||||
// The range is still the same, 1200-3000(4200), but adjusted for base
|
||||
database.GetFactionData(&fm, GetClass(), GetRace(), GetDeity(),
|
||||
database.GetFactionData(&fm, GetClass(), GetFactionRace(), GetDeity(),
|
||||
faction_id);
|
||||
|
||||
// Adjust the amount you can go up or down so the resulting range
|
||||
@@ -7839,9 +7862,9 @@ void Client::SetFactionLevel2(uint32 char_id, int32 faction_id, uint8 char_class
|
||||
// min or above max by not allowing any earn/loss in those directions.
|
||||
// At least one faction starts out way below min, so we don't want
|
||||
// to allow loses in those cases, just massive gains.
|
||||
this_faction_min = MIN_PERSONAL_FACTION - fm.base;
|
||||
this_faction_min = fm.min - fm.base;
|
||||
this_faction_min = std::min(0, this_faction_min);
|
||||
this_faction_max = MAX_PERSONAL_FACTION - fm.base;
|
||||
this_faction_max = fm.max - fm.base;
|
||||
this_faction_max = std::max(0, this_faction_max);
|
||||
|
||||
//Get the faction modifiers
|
||||
@@ -7930,9 +7953,15 @@ return;
|
||||
int32 Client::GetModCharacterFactionLevel(int32 faction_id) {
|
||||
int32 Modded = GetCharacterFactionLevel(faction_id);
|
||||
FactionMods fm;
|
||||
if (database.GetFactionData(&fm, GetClass(), GetRace(), GetDeity(), faction_id))
|
||||
if (database.GetFactionData(&fm, GetClass(), GetFactionRace(), GetDeity(), faction_id))
|
||||
{
|
||||
Modded += fm.base + fm.class_mod + fm.race_mod + fm.deity_mod;
|
||||
|
||||
//Tack on any bonuses from Alliance type spell effects
|
||||
Modded += GetFactionBonus(faction_id);
|
||||
Modded += GetItemFactionBonus(faction_id);
|
||||
}
|
||||
|
||||
return Modded;
|
||||
}
|
||||
|
||||
@@ -7945,7 +7974,7 @@ void Client::MerchantRejectMessage(Mob *merchant, int primaryfaction)
|
||||
|
||||
// If a faction is involved, get the data.
|
||||
if (primaryfaction > 0) {
|
||||
if (database.GetFactionData(&fmod, GetClass(), GetRace(), GetDeity(), primaryfaction)) {
|
||||
if (database.GetFactionData(&fmod, GetClass(), GetFactionRace(), GetDeity(), primaryfaction)) {
|
||||
tmpFactionValue = GetCharacterFactionLevel(primaryfaction);
|
||||
lowestvalue = std::min(std::min(tmpFactionValue, fmod.deity_mod),
|
||||
std::min(fmod.class_mod, fmod.race_mod));
|
||||
@@ -9126,4 +9155,4 @@ bool Client::GotoPlayer(std::string player_name)
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
+9
-1
@@ -781,6 +781,8 @@ public:
|
||||
void UnmemSpell(int slot, bool update_client = true);
|
||||
void UnmemSpellBySpellID(int32 spell_id);
|
||||
void UnmemSpellAll(bool update_client = true);
|
||||
uint16 FindMemmedSpellBySlot(int slot);
|
||||
int MemmedCount();
|
||||
void ScribeSpell(uint16 spell_id, int slot, bool update_client = true);
|
||||
void UnscribeSpell(int slot, bool update_client = true);
|
||||
void UnscribeSpellAll(bool update_client = true);
|
||||
@@ -791,7 +793,9 @@ public:
|
||||
uint32 GetCharMaxLevelFromQGlobal();
|
||||
uint32 GetCharMaxLevelFromBucket();
|
||||
|
||||
inline bool IsStanding() const {return (playeraction == 0);}
|
||||
inline bool IsSitting() const {return (playeraction == 1);}
|
||||
inline bool IsCrouching() const {return (playeraction == 2);}
|
||||
inline bool IsBecomeNPC() const { return npcflag; }
|
||||
inline uint8 GetBecomeNPCLevel() const { return npclevel; }
|
||||
inline void SetBecomeNPC(bool flag) { npcflag = flag; }
|
||||
@@ -1638,18 +1642,22 @@ private:
|
||||
#ifdef BOTS
|
||||
struct BotOwnerOptions {
|
||||
bool death_marquee;
|
||||
bool stats_update;
|
||||
};
|
||||
|
||||
BotOwnerOptions bot_owner_options;
|
||||
|
||||
const BotOwnerOptions DefaultBotOwnerOptions = {
|
||||
false // death_marquee
|
||||
false, // death_marquee
|
||||
false // stats_update
|
||||
};
|
||||
|
||||
public:
|
||||
void SetBotOptionDeathMarquee(bool flag) { bot_owner_options.death_marquee = flag; }
|
||||
void SetBotOptionStatsUpdate(bool flag) { bot_owner_options.stats_update = flag; }
|
||||
|
||||
bool GetBotOptionDeathMarquee() const { return bot_owner_options.death_marquee; }
|
||||
bool GetBotOptionStatsUpdate() const { return bot_owner_options.stats_update; }
|
||||
|
||||
private:
|
||||
#endif
|
||||
|
||||
+29
-26
@@ -530,10 +530,14 @@ void Client::CompleteConnect()
|
||||
SendAppearancePacket(AT_GuildID, GuildID(), false);
|
||||
SendAppearancePacket(AT_GuildRank, rank, false);
|
||||
}
|
||||
for (uint32 spellInt = 0; spellInt < EQEmu::spells::SPELLBOOK_SIZE; spellInt++) {
|
||||
if (m_pp.spell_book[spellInt] < 3 || m_pp.spell_book[spellInt] > 50000)
|
||||
|
||||
// moved to dbload and translators since we iterate there also .. keep m_pp values whatever they are when they get here
|
||||
/*const auto sbs = EQEmu::spells::DynamicLookup(ClientVersion(), GetGM())->SpellbookSize;
|
||||
for (uint32 spellInt = 0; spellInt < sbs; ++spellInt) {
|
||||
if (m_pp.spell_book[spellInt] < 3 || m_pp.spell_book[spellInt] > EQEmu::spells::SPELL_ID_MAX)
|
||||
m_pp.spell_book[spellInt] = 0xFFFFFFFF;
|
||||
}
|
||||
}*/
|
||||
|
||||
//SendAATable();
|
||||
|
||||
if (GetHideMe()) Message(13, "[GM] You are currently hidden to all clients");
|
||||
@@ -1154,6 +1158,7 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
|
||||
SetClientVersion(Connection()->ClientVersion());
|
||||
m_ClientVersionBit = EQEmu::versions::ConvertClientVersionToClientVersionBit(Connection()->ClientVersion());
|
||||
|
||||
m_pp.SetPlayerProfileVersion(m_ClientVersion);
|
||||
m_inv.SetInventoryVersion(m_ClientVersion);
|
||||
|
||||
/* Antighost code
|
||||
@@ -1409,12 +1414,11 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
|
||||
if (m_pp.ldon_points_tak < 0 || m_pp.ldon_points_tak > 2000000000) { m_pp.ldon_points_tak = 0; }
|
||||
if (m_pp.ldon_points_available < 0 || m_pp.ldon_points_available > 2000000000) { m_pp.ldon_points_available = 0; }
|
||||
|
||||
// need to rework .. not until full scope of change is accounted for, though
|
||||
if (RuleB(World, UseClientBasedExpansionSettings)) {
|
||||
m_pp.expansions = EQEmu::expansions::ConvertClientVersionToExpansionMask(ClientVersion());
|
||||
m_pp.expansions = EQEmu::expansions::ConvertClientVersionToExpansionsMask(ClientVersion());
|
||||
}
|
||||
else {
|
||||
m_pp.expansions = RuleI(World, ExpansionSettings);
|
||||
m_pp.expansions = (RuleI(World, ExpansionSettings) & EQEmu::expansions::ConvertClientVersionToExpansionsMask(ClientVersion()));
|
||||
}
|
||||
|
||||
if (!database.LoadAlternateAdvancement(this)) {
|
||||
@@ -1524,7 +1528,7 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
|
||||
}
|
||||
|
||||
#ifdef BOTS
|
||||
botdb.LoadOwnerOptions(this);
|
||||
database.botdb.LoadOwnerOptions(this);
|
||||
// TODO: mod below function for loading spawned botgroups
|
||||
Bot::LoadAndSpawnAllZonedBots(this);
|
||||
#endif
|
||||
@@ -1587,8 +1591,9 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
|
||||
if ((m_pp.RestTimer > RuleI(Character, RestRegenTimeToActivate)) && (m_pp.RestTimer > RuleI(Character, RestRegenRaidTimeToActivate)))
|
||||
m_pp.RestTimer = 0;
|
||||
|
||||
/* This checksum should disappear once dynamic structs are in... each struct strategy will do it */
|
||||
CRC32::SetEQChecksum((unsigned char*)&m_pp, sizeof(PlayerProfile_Struct) - 4);
|
||||
/* This checksum should disappear once dynamic structs are in... each struct strategy will do it */ // looks to be in place now
|
||||
//CRC32::SetEQChecksum((unsigned char*)&m_pp, sizeof(PlayerProfile_Struct) - sizeof(m_pp.m_player_profile_version) - 4);
|
||||
// m_pp.checksum = 0; // All server out-bound player profile packets are now translated - no need to waste cycles calculating this...
|
||||
|
||||
outapp = new EQApplicationPacket(OP_PlayerProfile, sizeof(PlayerProfile_Struct));
|
||||
|
||||
@@ -2807,24 +2812,19 @@ void Client::Handle_OP_ApplyPoison(const EQApplicationPacket *app)
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 ApplyPoisonSuccessResult = 0;
|
||||
ApplyPoison_Struct* ApplyPoisonData = (ApplyPoison_Struct*)app->pBuffer;
|
||||
|
||||
uint32 ApplyPoisonSuccessResult = 0;
|
||||
|
||||
const EQEmu::ItemInstance* PrimaryWeapon = GetInv().GetItem(EQEmu::invslot::slotPrimary);
|
||||
const EQEmu::ItemInstance* SecondaryWeapon = GetInv().GetItem(EQEmu::invslot::slotSecondary);
|
||||
const EQEmu::ItemInstance* PoisonItemInstance = GetInv()[ApplyPoisonData->inventorySlot];
|
||||
const EQEmu::ItemData* poison=PoisonItemInstance->GetItem();
|
||||
const EQEmu::ItemData* primary=nullptr;
|
||||
const EQEmu::ItemData* secondary=nullptr;
|
||||
bool IsPoison = PoisonItemInstance &&
|
||||
(poison->ItemType == EQEmu::item::ItemTypePoison);
|
||||
const EQEmu::ItemInstance* PoisonItemInstance = GetInv().GetItem(ApplyPoisonData->inventorySlot);
|
||||
|
||||
if (PrimaryWeapon) {
|
||||
primary=PrimaryWeapon->GetItem();
|
||||
}
|
||||
const EQEmu::ItemData* primary = (PrimaryWeapon ? PrimaryWeapon->GetItem() : nullptr);
|
||||
const EQEmu::ItemData* secondary = (SecondaryWeapon ? SecondaryWeapon->GetItem() : nullptr);
|
||||
const EQEmu::ItemData* poison = (PoisonItemInstance ? PoisonItemInstance->GetItem() : nullptr);
|
||||
|
||||
if (SecondaryWeapon) {
|
||||
secondary=SecondaryWeapon->GetItem();
|
||||
}
|
||||
bool IsPoison = (poison && poison->ItemType == EQEmu::item::ItemTypePoison);
|
||||
|
||||
if (IsPoison && GetClass() == ROGUE) {
|
||||
|
||||
@@ -4623,7 +4623,7 @@ void Client::Handle_OP_Consider(const EQApplicationPacket *app)
|
||||
con->playerid = GetID();
|
||||
con->targetid = conin->targetid;
|
||||
if (tmob->IsNPC())
|
||||
con->faction = GetFactionLevel(character_id, tmob->GetNPCTypeID(), race, class_, deity, (tmob->IsNPC()) ? tmob->CastToNPC()->GetPrimaryFaction() : 0, tmob); // Dec. 20, 2001; TODO: Send the players proper deity
|
||||
con->faction = GetFactionLevel(character_id, tmob->GetNPCTypeID(), GetFactionRace(), class_, deity, (tmob->IsNPC()) ? tmob->CastToNPC()->GetPrimaryFaction() : 0, tmob); // Dec. 20, 2001; TODO: Send the players proper deity
|
||||
else
|
||||
con->faction = 1;
|
||||
con->level = GetLevelCon(tmob->GetLevel());
|
||||
@@ -5263,7 +5263,7 @@ void Client::Handle_OP_DeleteSpell(const EQApplicationPacket *app)
|
||||
EQApplicationPacket* outapp = app->Copy();
|
||||
DeleteSpell_Struct* dss = (DeleteSpell_Struct*)outapp->pBuffer;
|
||||
|
||||
if (dss->spell_slot < 0 || dss->spell_slot > int(EQEmu::spells::SPELLBOOK_SIZE))
|
||||
if (dss->spell_slot < 0 || dss->spell_slot >= EQEmu::spells::DynamicLookup(ClientVersion(), GetGM())->SpellbookSize)
|
||||
return;
|
||||
|
||||
if (m_pp.spell_book[dss->spell_slot] != SPELLBOOK_UNKNOWN) {
|
||||
@@ -9394,7 +9394,7 @@ void Client::Handle_OP_MercenaryCommand(const EQApplicationPacket *app)
|
||||
//check to see if selected option is a valid stance slot (option is the slot the stance is in, not the actual stance)
|
||||
if (option >= 0 && option < numStances)
|
||||
{
|
||||
merc->SetStance(mercTemplate->Stances[option]);
|
||||
merc->SetStance((EQEmu::constants::StanceType)mercTemplate->Stances[option]);
|
||||
GetMercInfo().Stance = mercTemplate->Stances[option];
|
||||
|
||||
Log(Logs::General, Logs::Mercenaries, "Set Stance: %u for %s (%s)", merc->GetStance(), merc->GetName(), GetName());
|
||||
@@ -13338,7 +13338,10 @@ void Client::Handle_OP_SwapSpell(const EQApplicationPacket *app)
|
||||
const SwapSpell_Struct* swapspell = (const SwapSpell_Struct*)app->pBuffer;
|
||||
int swapspelltemp;
|
||||
|
||||
if (swapspell->from_slot < 0 || swapspell->from_slot > EQEmu::spells::SPELLBOOK_SIZE || swapspell->to_slot < 0 || swapspell->to_slot > EQEmu::spells::SPELLBOOK_SIZE)
|
||||
const auto sbs = EQEmu::spells::DynamicLookup(ClientVersion(), GetGM())->SpellbookSize;
|
||||
if (swapspell->from_slot < 0 || swapspell->from_slot >= sbs)
|
||||
return;
|
||||
if (swapspell->to_slot < 0 || swapspell->to_slot >= sbs)
|
||||
return;
|
||||
|
||||
swapspelltemp = m_pp.spell_book[swapspell->from_slot];
|
||||
|
||||
+484
-113
@@ -52,8 +52,10 @@
|
||||
#include "../common/rulesys.h"
|
||||
#include "../common/serverinfo.h"
|
||||
#include "../common/string_util.h"
|
||||
#include "../say_link.h"
|
||||
#include "../common/say_link.h"
|
||||
#include "../common/eqemu_logsys.h"
|
||||
#include "../common/profanity_manager.h"
|
||||
#include "../common/net/eqstream.h"
|
||||
|
||||
#include "data_bucket.h"
|
||||
#include "command.h"
|
||||
@@ -277,6 +279,7 @@ int command_init(void)
|
||||
command_add("mystats", "- Show details about you or your pet", 50, command_mystats) ||
|
||||
command_add("name", "[newname] - Rename your player target", 150, command_name) ||
|
||||
command_add("netstats", "- Gets the network stats for a stream.", 200, command_netstats) ||
|
||||
command_add("network", "- Admin commands for the udp network interface.", 250, command_network) ||
|
||||
command_add("npccast", "[targetname/entityid] [spellid] - Causes NPC target to cast spellid on targetname/entityid", 80, command_npccast) ||
|
||||
command_add("npcedit", "[column] [value] - Mega NPC editing command", 100, command_npcedit) ||
|
||||
command_add("npcemote", "[message] - Make your NPC target emote a message.", 150, command_npcemote) ||
|
||||
@@ -307,6 +310,7 @@ int command_init(void)
|
||||
command_add("petitioninfo", "[petition number] - Get info about a petition", 20, command_petitioninfo) ||
|
||||
command_add("pf", "- Display additional mob coordinate and wandering data", 0, command_pf) ||
|
||||
command_add("picklock", "Analog for ldon pick lock for the newer clients since we still don't have it working.", 0, command_picklock) ||
|
||||
command_add("profanity", "Manage censored language.", 150, command_profanity) ||
|
||||
|
||||
#ifdef EQPROFILE
|
||||
command_add("profiledump", "- Dump profiling info to logs", 250, command_profiledump) ||
|
||||
@@ -841,18 +845,32 @@ void command_setanim(Client *c, const Seperator *sep)
|
||||
|
||||
void command_serverinfo(Client *c, const Seperator *sep)
|
||||
{
|
||||
#ifdef _WINDOWS
|
||||
char intbuffer [sizeof(unsigned long)];
|
||||
c->Message(0, "Operating system information.");
|
||||
c->Message(0, " %s", Ver_name);
|
||||
c->Message(0, " Build number: %s", ultoa(Ver_build, intbuffer, 10));
|
||||
c->Message(0, " Minor version: %s", ultoa(Ver_min, intbuffer, 10));
|
||||
c->Message(0, " Major version: %s", ultoa(Ver_maj, intbuffer, 10));
|
||||
c->Message(0, " Platform Id: %s", ultoa(Ver_pid, intbuffer, 10));
|
||||
#else
|
||||
char buffer[255];
|
||||
c->Message(0, "Operating system information: %s", GetOS(buffer));
|
||||
#endif
|
||||
auto os = EQ::GetOS();
|
||||
auto cpus = EQ::GetCPUs();
|
||||
auto pid = EQ::GetPID();
|
||||
auto rss = EQ::GetRSS();
|
||||
auto uptime = EQ::GetUptime();
|
||||
|
||||
c->Message(0, "Operating System Information");
|
||||
c->Message(0, "==================================================");
|
||||
c->Message(0, "System: %s", os.sysname.c_str());
|
||||
c->Message(0, "Release: %s", os.release.c_str());
|
||||
c->Message(0, "Version: %s", os.version.c_str());
|
||||
c->Message(0, "Machine: %s", os.machine.c_str());
|
||||
c->Message(0, "Uptime: %.2f seconds", uptime);
|
||||
c->Message(0, "==================================================");
|
||||
c->Message(0, "CPU Information");
|
||||
c->Message(0, "==================================================");
|
||||
for (size_t i = 0; i < cpus.size(); ++i) {
|
||||
auto &cp = cpus[i];
|
||||
c->Message(0, "CPU #%i: %s, Speed: %.2fGhz", i, cp.model.c_str(), cp.speed);
|
||||
}
|
||||
c->Message(0, "==================================================");
|
||||
c->Message(0, "Process Information");
|
||||
c->Message(0, "==================================================");
|
||||
c->Message(0, "PID: %u", pid);
|
||||
c->Message(0, "RSS: %.2f MB", rss / 1048576.0);
|
||||
c->Message(0, "==================================================");
|
||||
}
|
||||
|
||||
void command_getvariable(Client *c, const Seperator *sep)
|
||||
@@ -6407,34 +6425,29 @@ void command_beardcolor(Client *c, const Seperator *sep)
|
||||
|
||||
void command_scribespells(Client *c, const Seperator *sep)
|
||||
{
|
||||
uint8 max_level, min_level;
|
||||
uint16 book_slot, curspell, count;
|
||||
Client *t=c;
|
||||
Client *t = c;
|
||||
if (c->GetTarget() && c->GetTarget()->IsClient() && c->GetGM())
|
||||
t = c->GetTarget()->CastToClient();
|
||||
|
||||
if(c->GetTarget() && c->GetTarget()->IsClient() && c->GetGM())
|
||||
t=c->GetTarget()->CastToClient();
|
||||
|
||||
if(!sep->arg[1][0])
|
||||
{
|
||||
if(sep->argnum < 1 || !sep->IsNumber(1)) {
|
||||
c->Message(0, "FORMAT: #scribespells <max level> <min level>");
|
||||
return;
|
||||
}
|
||||
|
||||
max_level = (uint8)atoi(sep->arg[1]);
|
||||
if (!c->GetGM() && max_level > RuleI(Character, MaxLevel))
|
||||
max_level = RuleI(Character, MaxLevel); //default to Character:MaxLevel if we're not a GM & it's higher than the max level
|
||||
min_level = sep->arg[2][0] ? (uint8)atoi(sep->arg[2]) : 1; //default to 1 if there isn't a 2nd argument
|
||||
if (!c->GetGM() && min_level > RuleI(Character, MaxLevel))
|
||||
min_level = RuleI(Character, MaxLevel); //default to Character:MaxLevel if we're not a GM & it's higher than the max level
|
||||
uint8 max_level = (uint8)atol(sep->arg[1]);
|
||||
if (!c->GetGM() && max_level > (uint8)RuleI(Character, MaxLevel))
|
||||
max_level = (uint8)RuleI(Character, MaxLevel); // default to Character:MaxLevel if we're not a GM & it's higher than the max level
|
||||
|
||||
uint8 min_level = (sep->IsNumber(2) ? (uint8)atol(sep->arg[2]) : 1); // default to 1 if there isn't a 2nd argument
|
||||
if (!c->GetGM() && min_level > (uint8)RuleI(Character, MaxLevel))
|
||||
min_level = (uint8)RuleI(Character, MaxLevel); // default to Character:MaxLevel if we're not a GM & it's higher than the max level
|
||||
|
||||
if(max_level < 1 || min_level < 1)
|
||||
{
|
||||
if(max_level < 1 || min_level < 1) {
|
||||
c->Message(0, "ERROR: Level must be greater than 1.");
|
||||
return;
|
||||
}
|
||||
if (min_level > max_level) {
|
||||
c->Message(0, "Error: Min Level must be less than or equal to Max Level.");
|
||||
c->Message(0, "ERROR: Min Level must be less than or equal to Max Level.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -6443,34 +6456,71 @@ void command_scribespells(Client *c, const Seperator *sep)
|
||||
c->Message(0, "Scribing spells for %s.", t->GetName());
|
||||
Log(Logs::General, Logs::Normal, "Scribe spells request for %s from %s, levels: %u -> %u", t->GetName(), c->GetName(), min_level, max_level);
|
||||
|
||||
for(curspell = 0, book_slot = t->GetNextAvailableSpellBookSlot(), count = 0; curspell < SPDAT_RECORDS && book_slot < EQEmu::spells::SPELLBOOK_SIZE; curspell++, book_slot = t->GetNextAvailableSpellBookSlot(book_slot))
|
||||
{
|
||||
if
|
||||
(
|
||||
spells[curspell].classes[WARRIOR] != 0 && // check if spell exists
|
||||
spells[curspell].classes[t->GetPP().class_-1] <= max_level && //maximum level
|
||||
spells[curspell].classes[t->GetPP().class_-1] >= min_level && //minimum level
|
||||
spells[curspell].skill != 52
|
||||
)
|
||||
{
|
||||
if (book_slot == -1) { //no more book slots
|
||||
t->Message(13, "Unable to scribe spell %s (%u) to spellbook: no more spell book slots available.", spells[curspell].name, curspell);
|
||||
if (t != c)
|
||||
c->Message(13, "Error scribing spells: %s ran out of spell book slots on spell %s (%u)", t->GetName(), spells[curspell].name, curspell);
|
||||
break;
|
||||
}
|
||||
if(!IsDiscipline(curspell) && !t->HasSpellScribed(curspell)) { //isn't a discipline & we don't already have it scribed
|
||||
t->ScribeSpell(curspell, book_slot);
|
||||
count++;
|
||||
}
|
||||
int book_slot = t->GetNextAvailableSpellBookSlot();
|
||||
int spell_id = 0;
|
||||
int count = 0;
|
||||
|
||||
for ( ; spell_id < SPDAT_RECORDS && book_slot < EQEmu::spells::SPELLBOOK_SIZE; ++spell_id) {
|
||||
if (book_slot == -1) {
|
||||
t->Message(
|
||||
13,
|
||||
"Unable to scribe spell %s (%i) to spellbook: no more spell book slots available.",
|
||||
((spell_id >= 0 && spell_id < SPDAT_RECORDS) ? spells[spell_id].name : "Out-of-range"),
|
||||
spell_id
|
||||
);
|
||||
if (t != c)
|
||||
c->Message(
|
||||
13,
|
||||
"Error scribing spells: %s ran out of spell book slots on spell %s (%i)",
|
||||
t->GetName(),
|
||||
((spell_id >= 0 && spell_id < SPDAT_RECORDS) ? spells[spell_id].name : "Out-of-range"),
|
||||
spell_id
|
||||
);
|
||||
|
||||
break;
|
||||
}
|
||||
if (spell_id < 0 || spell_id >= SPDAT_RECORDS) {
|
||||
c->Message(13, "FATAL ERROR: Spell id out-of-range (id: %i, min: 0, max: %i)", spell_id, SPDAT_RECORDS);
|
||||
return;
|
||||
}
|
||||
if (book_slot < 0 || book_slot >= EQEmu::spells::SPELLBOOK_SIZE) {
|
||||
c->Message(13, "FATAL ERROR: Book slot out-of-range (slot: %i, min: 0, max: %i)", book_slot, EQEmu::spells::SPELLBOOK_SIZE);
|
||||
return;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
if (spells[spell_id].classes[WARRIOR] == 0) // check if spell exists
|
||||
break;
|
||||
if (spells[spell_id].classes[t->GetPP().class_ - 1] > max_level) // maximum level
|
||||
break;
|
||||
if (spells[spell_id].classes[t->GetPP().class_ - 1] < min_level) // minimum level
|
||||
break;
|
||||
if (spells[spell_id].skill == 52)
|
||||
break;
|
||||
|
||||
uint16 spell_id_ = (uint16)spell_id;
|
||||
if ((spell_id_ != spell_id) || (spell_id != spell_id_)) {
|
||||
c->Message(13, "FATAL ERROR: Type conversion data loss with spell_id (%i != %u)", spell_id, spell_id_);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!IsDiscipline(spell_id_) && !t->HasSpellScribed(spell_id)) { // isn't a discipline & we don't already have it scribed
|
||||
t->ScribeSpell(spell_id_, book_slot);
|
||||
++count;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
book_slot = t->GetNextAvailableSpellBookSlot(book_slot);
|
||||
}
|
||||
|
||||
if (count > 0) {
|
||||
t->Message(0, "Successfully scribed %u spells.", count);
|
||||
t->Message(0, "Successfully scribed %i spells.", count);
|
||||
if (t != c)
|
||||
c->Message(0, "Successfully scribed %u spells for %s.", count, t->GetName());
|
||||
} else {
|
||||
c->Message(0, "Successfully scribed %i spells for %s.", count, t->GetName());
|
||||
}
|
||||
else {
|
||||
t->Message(0, "No spells scribed.");
|
||||
if (t != c)
|
||||
c->Message(0, "No spells scribed for %s.", t->GetName());
|
||||
@@ -8726,28 +8776,24 @@ void command_reloadtitles(Client *c, const Seperator *sep)
|
||||
|
||||
void command_traindisc(Client *c, const Seperator *sep)
|
||||
{
|
||||
uint8 max_level, min_level;
|
||||
uint16 curspell, count;
|
||||
Client *t=c;
|
||||
Client *t = c;
|
||||
if (c->GetTarget() && c->GetTarget()->IsClient() && c->GetGM())
|
||||
t = c->GetTarget()->CastToClient();
|
||||
|
||||
if(c->GetTarget() && c->GetTarget()->IsClient() && c->GetGM())
|
||||
t=c->GetTarget()->CastToClient();
|
||||
|
||||
if(!sep->arg[1][0])
|
||||
{
|
||||
if (sep->argnum < 1 || !sep->IsNumber(1)) {
|
||||
c->Message(0, "FORMAT: #traindisc <max level> <min level>");
|
||||
return;
|
||||
}
|
||||
|
||||
max_level = (uint8)atoi(sep->arg[1]);
|
||||
if (!c->GetGM() && max_level > RuleI(Character, MaxLevel))
|
||||
max_level = RuleI(Character, MaxLevel); //default to Character:MaxLevel if we're not a GM & it's higher than the max level
|
||||
min_level = sep->arg[2][0] ? (uint8)atoi(sep->arg[2]) : 1; //default to 1 if there isn't a 2nd argument
|
||||
if (!c->GetGM() && min_level > RuleI(Character, MaxLevel))
|
||||
min_level = RuleI(Character, MaxLevel); //default to Character:MaxLevel if we're not a GM & it's higher than the max level
|
||||
uint8 max_level = (uint8)atol(sep->arg[1]);
|
||||
if (!c->GetGM() && max_level >(uint8)RuleI(Character, MaxLevel))
|
||||
max_level = (uint8)RuleI(Character, MaxLevel); // default to Character:MaxLevel if we're not a GM & it's higher than the max level
|
||||
|
||||
if(max_level < 1 || min_level < 1)
|
||||
{
|
||||
uint8 min_level = (sep->IsNumber(2) ? (uint8)atol(sep->arg[2]) : 1); // default to 1 if there isn't a 2nd argument
|
||||
if (!c->GetGM() && min_level > (uint8)RuleI(Character, MaxLevel))
|
||||
min_level = (uint8)RuleI(Character, MaxLevel); // default to Character:MaxLevel if we're not a GM & it's higher than the max level
|
||||
|
||||
if(max_level < 1 || min_level < 1) {
|
||||
c->Message(0, "ERROR: Level must be greater than 1.");
|
||||
return;
|
||||
}
|
||||
@@ -8761,35 +8807,58 @@ void command_traindisc(Client *c, const Seperator *sep)
|
||||
c->Message(0, "Training disciplines for %s.", t->GetName());
|
||||
Log(Logs::General, Logs::Normal, "Train disciplines request for %s from %s, levels: %u -> %u", t->GetName(), c->GetName(), min_level, max_level);
|
||||
|
||||
for(curspell = 0, count = 0; curspell < SPDAT_RECORDS; curspell++)
|
||||
{
|
||||
if
|
||||
(
|
||||
spells[curspell].classes[WARRIOR] != 0 && // check if spell exists
|
||||
spells[curspell].classes[t->GetPP().class_-1] <= max_level && //maximum level
|
||||
spells[curspell].classes[t->GetPP().class_-1] >= min_level && //minimum level
|
||||
spells[curspell].skill != 52
|
||||
)
|
||||
{
|
||||
if(IsDiscipline(curspell)){
|
||||
//we may want to come up with a function like Client::GetNextAvailableSpellBookSlot() to help speed this up a little
|
||||
for(int r = 0; r < MAX_PP_DISCIPLINES; r++) {
|
||||
if(t->GetPP().disciplines.values[r] == curspell) {
|
||||
t->Message(13, "You already know this discipline.");
|
||||
break; //continue the 1st loop
|
||||
} else if(t->GetPP().disciplines.values[r] == 0) {
|
||||
t->GetPP().disciplines.values[r] = curspell;
|
||||
database.SaveCharacterDisc(t->CharacterID(), r, curspell);
|
||||
t->SendDisciplineUpdate();
|
||||
t->Message(0, "You have learned a new discipline!");
|
||||
count++; //success counter
|
||||
break; //continue the 1st loop
|
||||
} //if we get to this point, there's already a discipline in this slot, so we continue onto the next slot
|
||||
}
|
||||
int spell_id = 0;
|
||||
int count = 0;
|
||||
|
||||
bool change = false;
|
||||
|
||||
for( ; spell_id < SPDAT_RECORDS; ++spell_id) {
|
||||
if (spell_id < 0 || spell_id >= SPDAT_RECORDS) {
|
||||
c->Message(13, "FATAL ERROR: Spell id out-of-range (id: %i, min: 0, max: %i)", spell_id, SPDAT_RECORDS);
|
||||
return;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
if (spells[spell_id].classes[WARRIOR] == 0) // check if spell exists
|
||||
break;
|
||||
if (spells[spell_id].classes[t->GetPP().class_ - 1] > max_level) // maximum level
|
||||
break;
|
||||
if (spells[spell_id].classes[t->GetPP().class_ - 1] < min_level) // minimum level
|
||||
break;
|
||||
if (spells[spell_id].skill == 52)
|
||||
break;
|
||||
|
||||
uint16 spell_id_ = (uint16)spell_id;
|
||||
if ((spell_id_ != spell_id) || (spell_id != spell_id_)) {
|
||||
c->Message(13, "FATAL ERROR: Type conversion data loss with spell_id (%i != %u)", spell_id, spell_id_);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!IsDiscipline(spell_id_))
|
||||
break;
|
||||
|
||||
for (uint32 r = 0; r < MAX_PP_DISCIPLINES; ++r) {
|
||||
if (t->GetPP().disciplines.values[r] == spell_id_) {
|
||||
t->Message(13, "You already know this discipline.");
|
||||
break; // continue the 1st loop
|
||||
}
|
||||
else if (t->GetPP().disciplines.values[r] == 0) {
|
||||
t->GetPP().disciplines.values[r] = spell_id_;
|
||||
database.SaveCharacterDisc(t->CharacterID(), r, spell_id_);
|
||||
change = true;
|
||||
t->Message(0, "You have learned a new discipline!");
|
||||
++count; // success counter
|
||||
break; // continue the 1st loop
|
||||
} // if we get to this point, there's already a discipline in this slot, so we continue onto the next slot
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (change)
|
||||
t->SendDisciplineUpdate();
|
||||
|
||||
if (count > 0) {
|
||||
t->Message(0, "Successfully trained %u disciplines.", count);
|
||||
if (t != c)
|
||||
@@ -9429,23 +9498,77 @@ void command_netstats(Client *c, const Seperator *sep)
|
||||
{
|
||||
if(c)
|
||||
{
|
||||
if(c->GetTarget() && c->GetTarget()->IsClient())
|
||||
{
|
||||
c->Message(0, "Sent:");
|
||||
c->Message(0, "Total: %u, per second: %u", c->GetTarget()->CastToClient()->Connection()->GetBytesSent(),
|
||||
c->GetTarget()->CastToClient()->Connection()->GetBytesSentPerSecond());
|
||||
c->Message(0, "Recieved:");
|
||||
c->Message(0, "Total: %u, per second: %u", c->GetTarget()->CastToClient()->Connection()->GetBytesRecieved(),
|
||||
c->GetTarget()->CastToClient()->Connection()->GetBytesRecvPerSecond());
|
||||
auto client = c;
|
||||
if (c->GetTarget() && c->GetTarget()->IsClient()) {
|
||||
client = c->GetTarget()->CastToClient();
|
||||
}
|
||||
|
||||
if (strcasecmp(sep->arg[1], "reset") == 0) {
|
||||
auto connection = c->Connection();
|
||||
c->Message(0, "Resetting client stats (packet loss will not read correctly after reset).");
|
||||
connection->ResetStats();
|
||||
return;
|
||||
}
|
||||
|
||||
auto connection = c->Connection();
|
||||
auto opts = connection->GetManager()->GetOptions();
|
||||
auto eqs_stats = connection->GetStats();
|
||||
auto &stats = eqs_stats.DaybreakStats;
|
||||
auto now = EQ::Net::Clock::now();
|
||||
auto sec_since_stats_reset = std::chrono::duration_cast<std::chrono::duration<double>>(now - stats.created).count();
|
||||
|
||||
c->Message(0, "Netstats:");
|
||||
c->Message(0, "--------------------------------------------------------------------");
|
||||
c->Message(0, "Sent Bytes: %u (%.2f/sec)", stats.sent_bytes, stats.sent_bytes / sec_since_stats_reset);
|
||||
c->Message(0, "Recv Bytes: %u (%.2f/sec)", stats.recv_bytes, stats.recv_bytes / sec_since_stats_reset);
|
||||
c->Message(0, "Bytes Before Encode (Sent): %u, Compression Rate: %.2f%%", stats.bytes_before_encode,
|
||||
static_cast<double>(stats.bytes_before_encode - stats.sent_bytes) / static_cast<double>(stats.bytes_before_encode) * 100.0);
|
||||
c->Message(0, "Bytes After Decode (Recv): %u, Compression Rate: %.2f%%", stats.bytes_after_decode,
|
||||
static_cast<double>(stats.bytes_after_decode - stats.recv_bytes) / static_cast<double>(stats.bytes_after_decode) * 100.0);
|
||||
c->Message(0, "Min Ping: %u", stats.min_ping);
|
||||
c->Message(0, "Max Ping: %u", stats.max_ping);
|
||||
c->Message(0, "Last Ping: %u", stats.last_ping);
|
||||
c->Message(0, "Average Ping: %u", stats.avg_ping);
|
||||
c->Message(0, "--------------------------------------------------------------------");
|
||||
c->Message(0, "(Realtime) Recv Packets: %u (%.2f/sec)", stats.recv_packets, stats.recv_packets / sec_since_stats_reset);
|
||||
c->Message(0, "(Realtime) Sent Packets: %u (%.2f/sec)", stats.sent_packets, stats.sent_packets / sec_since_stats_reset);
|
||||
c->Message(0, "(Sync) Recv Packets: %u", stats.sync_recv_packets);
|
||||
c->Message(0, "(Sync) Sent Packets: %u", stats.sync_sent_packets);
|
||||
c->Message(0, "(Sync) Remote Recv Packets: %u", stats.sync_remote_recv_packets);
|
||||
c->Message(0, "(Sync) Remote Sent Packets: %u", stats.sync_remote_sent_packets);
|
||||
c->Message(0, "Packet Loss In: %.2f%%", 100.0 * (1.0 - static_cast<double>(stats.sync_recv_packets) / static_cast<double>(stats.sync_remote_sent_packets)));
|
||||
c->Message(0, "Packet Loss Out: %.2f%%", 100.0 * (1.0 - static_cast<double>(stats.sync_remote_recv_packets) / static_cast<double>(stats.sync_sent_packets)));
|
||||
c->Message(0, "--------------------------------------------------------------------");
|
||||
c->Message(0, "Resent Packets: %u (%.2f/sec)", stats.resent_packets, stats.resent_packets / sec_since_stats_reset);
|
||||
c->Message(0, "Resent Fragments: %u (%.2f/sec)", stats.resent_fragments, stats.resent_fragments / sec_since_stats_reset);
|
||||
c->Message(0, "Resent Non-Fragments: %u (%.2f/sec)", stats.resent_full, stats.resent_full / sec_since_stats_reset);
|
||||
c->Message(0, "Dropped Datarate Packets: %u (%.2f/sec)", stats.dropped_datarate_packets, stats.dropped_datarate_packets / sec_since_stats_reset);
|
||||
|
||||
if (opts.daybreak_options.outgoing_data_rate > 0.0) {
|
||||
c->Message(0, "Outgoing Link Saturation %.2f%% (%.2fkb/sec)", 100.0 * (1.0 - ((opts.daybreak_options.outgoing_data_rate - stats.datarate_remaining) / opts.daybreak_options.outgoing_data_rate)), opts.daybreak_options.outgoing_data_rate);
|
||||
}
|
||||
|
||||
if (strcasecmp(sep->arg[1], "full") == 0) {
|
||||
c->Message(0, "--------------------------------------------------------------------");
|
||||
c->Message(0, "Sent Packet Types");
|
||||
for (auto i = 0; i < _maxEmuOpcode; ++i) {
|
||||
auto cnt = eqs_stats.SentCount[i];
|
||||
if (cnt > 0) {
|
||||
c->Message(0, "%s: %u (%.2f / sec)", OpcodeNames[i], cnt, cnt / sec_since_stats_reset);
|
||||
}
|
||||
}
|
||||
|
||||
c->Message(0, "--------------------------------------------------------------------");
|
||||
c->Message(0, "Recv Packet Types");
|
||||
for (auto i = 0; i < _maxEmuOpcode; ++i) {
|
||||
auto cnt = eqs_stats.RecvCount[i];
|
||||
if (cnt > 0) {
|
||||
c->Message(0, "%s: %u (%.2f / sec)", OpcodeNames[i], cnt, cnt / sec_since_stats_reset);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
c->Message(0, "Sent:");
|
||||
c->Message(0, "Total: %u, per second: %u", c->Connection()->GetBytesSent(), c->Connection()->GetBytesSentPerSecond());
|
||||
c->Message(0, "Recieved:");
|
||||
c->Message(0, "Total: %u, per second: %u", c->Connection()->GetBytesRecieved(), c->Connection()->GetBytesRecvPerSecond());
|
||||
}
|
||||
|
||||
c->Message(0, "--------------------------------------------------------------------");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11041,6 +11164,68 @@ void command_picklock(Client *c, const Seperator *sep)
|
||||
}
|
||||
}
|
||||
|
||||
void command_profanity(Client *c, const Seperator *sep)
|
||||
{
|
||||
std::string arg1(sep->arg[1]);
|
||||
|
||||
while (true) {
|
||||
if (arg1.compare("list") == 0) {
|
||||
// do nothing
|
||||
}
|
||||
else if (arg1.compare("clear") == 0) {
|
||||
EQEmu::ProfanityManager::DeleteProfanityList(&database);
|
||||
auto pack = new ServerPacket(ServerOP_RefreshCensorship);
|
||||
worldserver.SendPacket(pack);
|
||||
safe_delete(pack);
|
||||
}
|
||||
else if (arg1.compare("add") == 0) {
|
||||
if (!EQEmu::ProfanityManager::AddProfanity(&database, sep->arg[2]))
|
||||
c->Message(CC_Red, "Could not add '%s' to the profanity list.", sep->arg[2]);
|
||||
auto pack = new ServerPacket(ServerOP_RefreshCensorship);
|
||||
worldserver.SendPacket(pack);
|
||||
safe_delete(pack);
|
||||
}
|
||||
else if (arg1.compare("del") == 0) {
|
||||
if (!EQEmu::ProfanityManager::RemoveProfanity(&database, sep->arg[2]))
|
||||
c->Message(CC_Red, "Could not delete '%s' from the profanity list.", sep->arg[2]);
|
||||
auto pack = new ServerPacket(ServerOP_RefreshCensorship);
|
||||
worldserver.SendPacket(pack);
|
||||
safe_delete(pack);
|
||||
}
|
||||
else if (arg1.compare("reload") == 0) {
|
||||
if (!EQEmu::ProfanityManager::UpdateProfanityList(&database))
|
||||
c->Message(CC_Red, "Could not reload the profanity list.");
|
||||
auto pack = new ServerPacket(ServerOP_RefreshCensorship);
|
||||
worldserver.SendPacket(pack);
|
||||
safe_delete(pack);
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
|
||||
std::string popup;
|
||||
const auto &list = EQEmu::ProfanityManager::GetProfanityList();
|
||||
for (const auto &iter : list) {
|
||||
popup.append(iter);
|
||||
popup.append("<br>");
|
||||
}
|
||||
if (list.empty())
|
||||
popup.append("** Censorship Inactive **<br>");
|
||||
else
|
||||
popup.append("** End of List **<br>");
|
||||
|
||||
c->SendPopupToClient("Profanity List", popup.c_str());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
c->Message(0, "Usage: #profanity [list] - shows profanity list");
|
||||
c->Message(0, "Usage: #profanity [clear] - deletes all entries");
|
||||
c->Message(0, "Usage: #profanity [add] [<word>] - adds entry");
|
||||
c->Message(0, "Usage: #profanity [del] [<word>] - deletes entry");
|
||||
c->Message(0, "Usage: #profanity [reload] - reloads profanity list");
|
||||
}
|
||||
|
||||
void command_mysql(Client *c, const Seperator *sep)
|
||||
{
|
||||
if(!sep->arg[1][0] || !sep->arg[2][0]) {
|
||||
@@ -11593,15 +11778,25 @@ void command_logs(Client *c, const Seperator *sep){
|
||||
safe_delete(pack);
|
||||
}
|
||||
/* #logs list_settings */
|
||||
if (strcasecmp(sep->arg[1], "list_settings") == 0 || (strcasecmp(sep->arg[1], "set") == 0 && strcasecmp(sep->arg[3], "") == 0)){
|
||||
if (strcasecmp(sep->arg[1], "list_settings") == 0 ||
|
||||
(strcasecmp(sep->arg[1], "set") == 0 && strcasecmp(sep->arg[3], "") == 0)) {
|
||||
c->Message(0, "[Category ID | console | file | gmsay | Category Description]");
|
||||
int redisplay_columns = 0;
|
||||
for (int i = 0; i < Logs::LogCategory::MaxCategoryID; i++){
|
||||
if (redisplay_columns == 10){
|
||||
for (int i = 0; i < Logs::LogCategory::MaxCategoryID; i++) {
|
||||
if (redisplay_columns == 10) {
|
||||
c->Message(0, "[Category ID | console | file | gmsay | Category Description]");
|
||||
redisplay_columns = 0;
|
||||
}
|
||||
c->Message(0, StringFormat("--- %i | %u | %u | %u | %s", i, LogSys.log_settings[i].log_to_console, LogSys.log_settings[i].log_to_file, LogSys.log_settings[i].log_to_gmsay, Logs::LogCategoryName[i]).c_str());
|
||||
c->Message(
|
||||
0,
|
||||
StringFormat(
|
||||
"--- %i | %u | %u | %u | %s",
|
||||
i,
|
||||
LogSys.log_settings[i].log_to_console,
|
||||
LogSys.log_settings[i].log_to_file,
|
||||
LogSys.log_settings[i].log_to_gmsay,
|
||||
Logs::LogCategoryName[i]
|
||||
).c_str());
|
||||
redisplay_columns++;
|
||||
}
|
||||
}
|
||||
@@ -12051,6 +12246,182 @@ void command_who(Client *c, const Seperator *sep)
|
||||
c->Message(5, message.c_str());
|
||||
}
|
||||
|
||||
void command_network(Client *c, const Seperator *sep)
|
||||
{
|
||||
if (!strcasecmp(sep->arg[1], "getopt"))
|
||||
{
|
||||
auto eqsi = c->Connection();
|
||||
auto manager = eqsi->GetManager();
|
||||
auto opts = manager->GetOptions();
|
||||
|
||||
if (!strcasecmp(sep->arg[2], "all"))
|
||||
{
|
||||
c->Message(0, "max_packet_size: %llu", (uint64_t)opts.daybreak_options.max_packet_size);
|
||||
c->Message(0, "max_connection_count: %llu", (uint64_t)opts.daybreak_options.max_connection_count);
|
||||
c->Message(0, "keepalive_delay_ms: %llu", (uint64_t)opts.daybreak_options.keepalive_delay_ms);
|
||||
c->Message(0, "resend_delay_factor: %.2f", opts.daybreak_options.resend_delay_factor);
|
||||
c->Message(0, "resend_delay_ms: %llu", (uint64_t)opts.daybreak_options.resend_delay_ms);
|
||||
c->Message(0, "resend_delay_min: %llu", (uint64_t)opts.daybreak_options.resend_delay_min);
|
||||
c->Message(0, "resend_delay_max: %llu", (uint64_t)opts.daybreak_options.resend_delay_max);
|
||||
c->Message(0, "connect_delay_ms: %llu", (uint64_t)opts.daybreak_options.connect_delay_ms);
|
||||
c->Message(0, "connect_stale_ms: %llu", (uint64_t)opts.daybreak_options.connect_stale_ms);
|
||||
c->Message(0, "stale_connection_ms: %llu", (uint64_t)opts.daybreak_options.stale_connection_ms);
|
||||
c->Message(0, "crc_length: %llu", (uint64_t)opts.daybreak_options.crc_length);
|
||||
c->Message(0, "hold_size: %llu", (uint64_t)opts.daybreak_options.hold_size);
|
||||
c->Message(0, "hold_length_ms: %llu", (uint64_t)opts.daybreak_options.hold_length_ms);
|
||||
c->Message(0, "simulated_in_packet_loss: %llu", (uint64_t)opts.daybreak_options.simulated_in_packet_loss);
|
||||
c->Message(0, "simulated_out_packet_loss: %llu", (uint64_t)opts.daybreak_options.simulated_out_packet_loss);
|
||||
c->Message(0, "tic_rate_hertz: %.2f", opts.daybreak_options.tic_rate_hertz);
|
||||
c->Message(0, "resend_timeout: %llu", (uint64_t)opts.daybreak_options.resend_timeout);
|
||||
c->Message(0, "connection_close_time: %llu", (uint64_t)opts.daybreak_options.connection_close_time);
|
||||
c->Message(0, "encode_passes[0]: %llu", (uint64_t)opts.daybreak_options.encode_passes[0]);
|
||||
c->Message(0, "encode_passes[1]: %llu", (uint64_t)opts.daybreak_options.encode_passes[1]);
|
||||
c->Message(0, "port: %llu", (uint64_t)opts.daybreak_options.port);
|
||||
}
|
||||
else {
|
||||
c->Message(0, "Unknown get option: %s", sep->arg[2]);
|
||||
c->Message(0, "Available options:");
|
||||
//Todo the rest of these when im less lazy.
|
||||
//c->Message(0, "max_packet_size");
|
||||
//c->Message(0, "max_connection_count");
|
||||
//c->Message(0, "keepalive_delay_ms");
|
||||
//c->Message(0, "resend_delay_factor");
|
||||
//c->Message(0, "resend_delay_ms");
|
||||
//c->Message(0, "resend_delay_min");
|
||||
//c->Message(0, "resend_delay_max");
|
||||
//c->Message(0, "connect_delay_ms");
|
||||
//c->Message(0, "connect_stale_ms");
|
||||
//c->Message(0, "stale_connection_ms");
|
||||
//c->Message(0, "crc_length");
|
||||
//c->Message(0, "hold_size");
|
||||
//c->Message(0, "hold_length_ms");
|
||||
//c->Message(0, "simulated_in_packet_loss");
|
||||
//c->Message(0, "simulated_out_packet_loss");
|
||||
//c->Message(0, "tic_rate_hertz");
|
||||
//c->Message(0, "resend_timeout");
|
||||
//c->Message(0, "connection_close_time");
|
||||
//c->Message(0, "encode_passes[0]");
|
||||
//c->Message(0, "encode_passes[1]");
|
||||
//c->Message(0, "port");
|
||||
c->Message(0, "all");
|
||||
}
|
||||
}
|
||||
else if (!strcasecmp(sep->arg[1], "setopt"))
|
||||
{
|
||||
auto eqsi = c->Connection();
|
||||
auto manager = eqsi->GetManager();
|
||||
auto opts = manager->GetOptions();
|
||||
|
||||
if (!strcasecmp(sep->arg[3], ""))
|
||||
{
|
||||
c->Message(0, "Missing value for set");
|
||||
return;
|
||||
}
|
||||
|
||||
std::string value = sep->arg[3];
|
||||
if (!strcasecmp(sep->arg[2], "max_connection_count"))
|
||||
{
|
||||
opts.daybreak_options.max_connection_count = std::stoull(value);
|
||||
manager->SetOptions(opts);
|
||||
}
|
||||
else if (!strcasecmp(sep->arg[2], "keepalive_delay_ms"))
|
||||
{
|
||||
opts.daybreak_options.keepalive_delay_ms = std::stoull(value);
|
||||
manager->SetOptions(opts);
|
||||
}
|
||||
else if (!strcasecmp(sep->arg[2], "resend_delay_factor"))
|
||||
{
|
||||
opts.daybreak_options.resend_delay_factor = std::stod(value);
|
||||
manager->SetOptions(opts);
|
||||
}
|
||||
else if (!strcasecmp(sep->arg[2], "resend_delay_ms"))
|
||||
{
|
||||
opts.daybreak_options.resend_delay_ms = std::stoull(value);
|
||||
manager->SetOptions(opts);
|
||||
}
|
||||
else if (!strcasecmp(sep->arg[2], "resend_delay_min"))
|
||||
{
|
||||
opts.daybreak_options.resend_delay_min = std::stoull(value);
|
||||
manager->SetOptions(opts);
|
||||
}
|
||||
else if (!strcasecmp(sep->arg[2], "resend_delay_max"))
|
||||
{
|
||||
opts.daybreak_options.resend_delay_max = std::stoull(value);
|
||||
manager->SetOptions(opts);
|
||||
}
|
||||
else if (!strcasecmp(sep->arg[2], "connect_delay_ms"))
|
||||
{
|
||||
opts.daybreak_options.connect_delay_ms = std::stoull(value);
|
||||
manager->SetOptions(opts);
|
||||
}
|
||||
else if (!strcasecmp(sep->arg[2], "connect_stale_ms"))
|
||||
{
|
||||
opts.daybreak_options.connect_stale_ms = std::stoull(value);
|
||||
manager->SetOptions(opts);
|
||||
}
|
||||
else if (!strcasecmp(sep->arg[2], "stale_connection_ms"))
|
||||
{
|
||||
opts.daybreak_options.stale_connection_ms = std::stoull(value);
|
||||
manager->SetOptions(opts);
|
||||
}
|
||||
else if (!strcasecmp(sep->arg[2], "hold_size"))
|
||||
{
|
||||
opts.daybreak_options.hold_size = std::stoull(value);
|
||||
manager->SetOptions(opts);
|
||||
}
|
||||
else if (!strcasecmp(sep->arg[2], "hold_length_ms"))
|
||||
{
|
||||
opts.daybreak_options.hold_length_ms = std::stoull(value);
|
||||
manager->SetOptions(opts);
|
||||
}
|
||||
else if (!strcasecmp(sep->arg[2], "simulated_in_packet_loss"))
|
||||
{
|
||||
opts.daybreak_options.simulated_in_packet_loss = std::stoull(value);
|
||||
manager->SetOptions(opts);
|
||||
}
|
||||
else if (!strcasecmp(sep->arg[2], "simulated_out_packet_loss"))
|
||||
{
|
||||
opts.daybreak_options.simulated_out_packet_loss = std::stoull(value);
|
||||
manager->SetOptions(opts);
|
||||
}
|
||||
else if (!strcasecmp(sep->arg[2], "resend_timeout"))
|
||||
{
|
||||
opts.daybreak_options.resend_timeout = std::stoull(value);
|
||||
manager->SetOptions(opts);
|
||||
}
|
||||
else if (!strcasecmp(sep->arg[2], "connection_close_time"))
|
||||
{
|
||||
opts.daybreak_options.connection_close_time = std::stoull(value);
|
||||
manager->SetOptions(opts);
|
||||
}
|
||||
else {
|
||||
c->Message(0, "Unknown set option: %s", sep->arg[2]);
|
||||
c->Message(0, "Available options:");
|
||||
c->Message(0, "max_connection_count");
|
||||
c->Message(0, "keepalive_delay_ms");
|
||||
c->Message(0, "resend_delay_factor");
|
||||
c->Message(0, "resend_delay_ms");
|
||||
c->Message(0, "resend_delay_min");
|
||||
c->Message(0, "resend_delay_max");
|
||||
c->Message(0, "connect_delay_ms");
|
||||
c->Message(0, "connect_stale_ms");
|
||||
c->Message(0, "stale_connection_ms");
|
||||
c->Message(0, "hold_size");
|
||||
c->Message(0, "hold_length_ms");
|
||||
c->Message(0, "simulated_in_packet_loss");
|
||||
c->Message(0, "simulated_out_packet_loss");
|
||||
c->Message(0, "resend_timeout");
|
||||
c->Message(0, "connection_close_time");
|
||||
}
|
||||
}
|
||||
else {
|
||||
c->Message(0, "Unknown command: %s", sep->arg[1]);
|
||||
c->Message(0, "Network commands avail:");
|
||||
c->Message(0, "getopt optname - Retrieve the current option value set.");
|
||||
c->Message(0, "setopt optname - Set the current option allowed.");
|
||||
}
|
||||
}
|
||||
|
||||
// All new code added to command.cpp should be BEFORE this comment line. Do no append code to this file below the BOTS code block.
|
||||
#ifdef BOTS
|
||||
#include "bot_command.h"
|
||||
|
||||
@@ -179,6 +179,7 @@ void command_mysqltest(Client *c, const Seperator *sep);
|
||||
void command_mystats(Client *c, const Seperator *sep);
|
||||
void command_name(Client *c, const Seperator *sep);
|
||||
void command_netstats(Client *c, const Seperator *sep);
|
||||
void command_network(Client *c, const Seperator *sep);
|
||||
void command_npccast(Client *c, const Seperator *sep);
|
||||
void command_npcedit(Client *c, const Seperator *sep);
|
||||
void command_npcemote(Client *c, const Seperator *sep);
|
||||
@@ -210,6 +211,7 @@ void command_permagender(Client *c, const Seperator *sep);
|
||||
void command_permarace(Client *c, const Seperator *sep);
|
||||
void command_petitioninfo(Client *c, const Seperator *sep);
|
||||
void command_picklock(Client *c, const Seperator *sep);
|
||||
void command_profanity(Client *c, const Seperator *sep);
|
||||
|
||||
#ifdef EQPROFILE
|
||||
void command_profiledump(Client *c, const Seperator *sep);
|
||||
|
||||
@@ -558,6 +558,7 @@ struct StatBonuses {
|
||||
int16 FeignedCastOnChance; // Percent Value
|
||||
bool PetCommands[PET_MAXCOMMANDS]; // SPA 267
|
||||
int FeignedMinionChance; // SPA 281 base1 = chance, just like normal FD
|
||||
int GrantForage; // affects max skill of forage as well as granting non-forage classes forage
|
||||
int aura_slots;
|
||||
int trap_slots;
|
||||
bool hunger; // Song of Sustenance -- min caps to 3500
|
||||
|
||||
+4
-1
@@ -152,7 +152,8 @@ Corpse::Corpse(NPC* in_npc, ItemList* in_itemlist, uint32 in_npctypeid, const NP
|
||||
in_npc->GetDeity(),in_npc->GetLevel(),in_npc->GetNPCTypeID(),in_npc->GetSize(),0,
|
||||
in_npc->GetPosition(), in_npc->GetInnateLightType(), in_npc->GetTexture(),in_npc->GetHelmTexture(),
|
||||
0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,EQEmu::TintProfile(),0xff,0,0,0,0,0,0,0,0,0,0,0,0,0,0),
|
||||
0,0,0,0,0,0,0,0,0,0,EQEmu::TintProfile(),0xff,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
(*in_npctypedata)->use_model),
|
||||
corpse_decay_timer(in_decaytime),
|
||||
corpse_rez_timer(0),
|
||||
corpse_delay_timer(RuleI(NPC, CorpseUnlockTimer)),
|
||||
@@ -258,6 +259,7 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob (
|
||||
0, // uint8 in_bracertexture,
|
||||
0, // uint8 in_handtexture,
|
||||
0, // uint8 in_legtexture,
|
||||
0,
|
||||
0 // uint8 in_feettexture,
|
||||
),
|
||||
corpse_decay_timer(RuleI(Character, CorpseDecayTimeMS)),
|
||||
@@ -484,6 +486,7 @@ EQEmu::TintProfile(),
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0),
|
||||
corpse_decay_timer(RuleI(Character, CorpseDecayTimeMS)),
|
||||
corpse_rez_timer(RuleI(Character, CorpseResTimeMS)),
|
||||
|
||||
+1
-1
@@ -1046,7 +1046,7 @@ void PerlembParser::ExportMobVariables(bool isPlayerQuest, bool isGlobalPlayerQu
|
||||
if (mob && npcmob && mob->IsClient()) {
|
||||
Client* client = mob->CastToClient();
|
||||
|
||||
fac = client->GetFactionLevel(client->CharacterID(), npcmob->GetID(), client->GetRace(),
|
||||
fac = client->GetFactionLevel(client->CharacterID(), npcmob->GetID(), client->GetFactionRace(),
|
||||
client->GetClass(), client->GetDeity(), npcmob->GetPrimaryFaction(), npcmob);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -36,7 +36,7 @@ Encounter::Encounter(const char* enc_name)
|
||||
:Mob
|
||||
(
|
||||
nullptr, nullptr, 0, 0, 0, INVISIBLE_MAN, 0, BT_NoTarget, 0, 0, 0, 0, 0, glm::vec4(0,0,0,0), 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, EQEmu::TintProfile(), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, EQEmu::TintProfile(), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
)
|
||||
{
|
||||
encounter_name[0] = 0;
|
||||
|
||||
+17
-6
@@ -286,6 +286,17 @@ Bot *Entity::CastToBot()
|
||||
#endif
|
||||
return static_cast<Bot *>(this);
|
||||
}
|
||||
|
||||
const Bot *Entity::CastToBot() const
|
||||
{
|
||||
#ifdef _EQDEBUG
|
||||
if (!IsBot()) {
|
||||
std::cout << "CastToBot error" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
return static_cast<const Bot *>(this);
|
||||
}
|
||||
#endif
|
||||
|
||||
EntityList::EntityList()
|
||||
@@ -509,16 +520,16 @@ void EntityList::MobProcess()
|
||||
}
|
||||
|
||||
if(mob_dead) {
|
||||
if(mob->IsNPC()) {
|
||||
entity_list.RemoveNPC(id);
|
||||
}
|
||||
else if(mob->IsMerc()) {
|
||||
if(mob->IsMerc()) {
|
||||
entity_list.RemoveMerc(id);
|
||||
#ifdef BOTS
|
||||
}
|
||||
#ifdef BOTS
|
||||
else if(mob->IsBot()) {
|
||||
entity_list.RemoveBot(id);
|
||||
}
|
||||
#endif
|
||||
else if(mob->IsNPC()) {
|
||||
entity_list.RemoveNPC(id);
|
||||
}
|
||||
else {
|
||||
#ifdef _WINDOWS
|
||||
@@ -4178,7 +4189,7 @@ void EntityList::ZoneWho(Client *c, Who_All_Struct *Who)
|
||||
WAPP2->RankMSGID = 12315;
|
||||
else if (ClientEntry->IsBuyer())
|
||||
WAPP2->RankMSGID = 6056;
|
||||
else if (ClientEntry->Admin() >= 10)
|
||||
else if (ClientEntry->Admin() >= 10 && ClientEntry->GetGM())
|
||||
WAPP2->RankMSGID = 12312;
|
||||
else
|
||||
WAPP2->RankMSGID = 0xFFFFFFFF;
|
||||
|
||||
@@ -116,6 +116,7 @@ public:
|
||||
|
||||
#ifdef BOTS
|
||||
Bot* CastToBot();
|
||||
const Bot* CastToBot() const;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
|
||||
+1
-1
@@ -182,7 +182,7 @@ bool Client::CanFish() {
|
||||
const float LineLength = RuleR(Watermap, FishingLineLength);
|
||||
int HeadingDegrees;
|
||||
|
||||
HeadingDegrees = (int) ((GetHeading()*360)/256);
|
||||
HeadingDegrees = (int) ((GetHeading()*360)/512);
|
||||
HeadingDegrees = HeadingDegrees % 360;
|
||||
|
||||
rodPosition.x = m_Position.x + RodLength * sin(HeadingDegrees * M_PI/180.0f);
|
||||
|
||||
+1
-1
@@ -98,7 +98,7 @@ uint32 Client::NukeItem(uint32 itemnum, uint8 where_to_check) {
|
||||
x++;
|
||||
}
|
||||
|
||||
DeleteItemInInventory(i, 0, ((((uint64)1 << (EQEmu::invslot::GENERAL_BEGIN + ((i - EQEmu::invbag::GENERAL_BAGS_BEGIN) / EQEmu::invbag::SLOT_COUNT))) & GetInv().GetLookup()->PossessionsBitmask) == 0));
|
||||
DeleteItemInInventory(i, 0, ((((uint64)1 << (EQEmu::invslot::GENERAL_BEGIN + ((i - EQEmu::invbag::GENERAL_BAGS_BEGIN) / EQEmu::invbag::SLOT_COUNT))) & GetInv().GetLookup()->PossessionsBitmask) != 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -550,6 +550,16 @@ void Lua_Client::UnmemSpellAll(bool update_client) {
|
||||
self->UnmemSpellAll(update_client);
|
||||
}
|
||||
|
||||
uint16 Lua_Client::FindMemmedSpellBySlot(int slot) {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->FindMemmedSpellBySlot(slot);
|
||||
}
|
||||
|
||||
int Lua_Client::MemmedCount() {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->MemmedCount();
|
||||
}
|
||||
|
||||
void Lua_Client::ScribeSpell(int spell_id, int slot) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->ScribeSpell(spell_id, slot);
|
||||
@@ -615,11 +625,21 @@ void Lua_Client::UntrainDiscAll(bool update_client) {
|
||||
self->UntrainDiscAll(update_client);
|
||||
}
|
||||
|
||||
bool Lua_Client::IsStanding() {
|
||||
Lua_Safe_Call_Bool();
|
||||
return self->IsStanding();
|
||||
}
|
||||
|
||||
bool Lua_Client::IsSitting() {
|
||||
Lua_Safe_Call_Bool();
|
||||
return self->IsSitting();
|
||||
}
|
||||
|
||||
bool Lua_Client::IsCrouching() {
|
||||
Lua_Safe_Call_Bool();
|
||||
return self->IsCrouching();
|
||||
}
|
||||
|
||||
void Lua_Client::SetFeigned(bool v) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->SetFeigned(v);
|
||||
@@ -1608,6 +1628,8 @@ luabind::scope lua_register_client() {
|
||||
.def("UnmemSpellBySpellID", (void(Lua_Client::*)(int32))&Lua_Client::UnmemSpellBySpellID)
|
||||
.def("UnmemSpellAll", (void(Lua_Client::*)(void))&Lua_Client::UnmemSpellAll)
|
||||
.def("UnmemSpellAll", (void(Lua_Client::*)(bool))&Lua_Client::UnmemSpellAll)
|
||||
.def("FindMemmedSpellBySlot", (uint16(Lua_Client::*)(int))&Lua_Client::FindMemmedSpellBySlot)
|
||||
.def("MemmedCount", (int(Lua_Client::*)(void))&Lua_Client::MemmedCount)
|
||||
.def("ScribeSpell", (void(Lua_Client::*)(int,int))&Lua_Client::ScribeSpell)
|
||||
.def("ScribeSpell", (void(Lua_Client::*)(int,int,bool))&Lua_Client::ScribeSpell)
|
||||
.def("UnscribeSpell", (void(Lua_Client::*)(int))&Lua_Client::UnscribeSpell)
|
||||
@@ -1621,7 +1643,9 @@ luabind::scope lua_register_client() {
|
||||
.def("UntrainDisc", (void(Lua_Client::*)(int,bool))&Lua_Client::UntrainDisc)
|
||||
.def("UntrainDiscAll", (void(Lua_Client::*)(void))&Lua_Client::UntrainDiscAll)
|
||||
.def("UntrainDiscAll", (void(Lua_Client::*)(bool))&Lua_Client::UntrainDiscAll)
|
||||
.def("IsStanding", (bool(Lua_Client::*)(void))&Lua_Client::IsStanding)
|
||||
.def("IsSitting", (bool(Lua_Client::*)(void))&Lua_Client::IsSitting)
|
||||
.def("IsCrouching", (bool(Lua_Client::*)(void))&Lua_Client::IsCrouching)
|
||||
.def("SetFeigned", (void(Lua_Client::*)(bool))&Lua_Client::SetFeigned)
|
||||
.def("GetFeigned", (bool(Lua_Client::*)(void))&Lua_Client::GetFeigned)
|
||||
.def("AutoSplitEnabled", (bool(Lua_Client::*)(void))&Lua_Client::AutoSplitEnabled)
|
||||
|
||||
@@ -135,6 +135,8 @@ public:
|
||||
void UnmemSpellBySpellID(int32 spell_id);
|
||||
void UnmemSpellAll();
|
||||
void UnmemSpellAll(bool update_client);
|
||||
uint16 FindMemmedSpellBySlot(int slot);
|
||||
int MemmedCount();
|
||||
void ScribeSpell(int spell_id, int slot);
|
||||
void ScribeSpell(int spell_id, int slot, bool update_client);
|
||||
void UnscribeSpell(int slot);
|
||||
@@ -148,7 +150,9 @@ public:
|
||||
void UntrainDisc(int slot, bool update_client);
|
||||
void UntrainDiscAll();
|
||||
void UntrainDiscAll(bool update_client);
|
||||
bool IsStanding();
|
||||
bool IsSitting();
|
||||
bool IsCrouching();
|
||||
void SetFeigned(bool v);
|
||||
bool GetFeigned();
|
||||
bool AutoSplitEnabled();
|
||||
|
||||
@@ -267,6 +267,11 @@ void Lua_Mob::ChangeSize(double in_size, bool no_restriction) {
|
||||
self->ChangeSize(static_cast<float>(in_size), no_restriction);
|
||||
}
|
||||
|
||||
void Lua_Mob::RandomizeFeatures(bool send_illusion, bool save_variables) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->RandomizeFeatures(send_illusion, save_variables);
|
||||
}
|
||||
|
||||
void Lua_Mob::GMMove(double x, double y, double z) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->GMMove(static_cast<float>(x), static_cast<float>(y), static_cast<float>(z));
|
||||
@@ -317,6 +322,16 @@ bool Lua_Mob::FindBuff(int spell_id) {
|
||||
return self->FindBuff(spell_id);
|
||||
}
|
||||
|
||||
uint16 Lua_Mob::FindBuffBySlot(int slot) {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->FindBuffBySlot(slot);
|
||||
}
|
||||
|
||||
uint32 Lua_Mob::BuffCount() {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->BuffCount();
|
||||
}
|
||||
|
||||
bool Lua_Mob::FindType(int type) {
|
||||
Lua_Safe_Call_Bool();
|
||||
return self->FindType(type);
|
||||
@@ -2086,6 +2101,11 @@ int Lua_Mob::GetWeaponDamageBonus(Lua_Item weapon, bool offhand) {
|
||||
return self->GetWeaponDamageBonus(weapon, offhand);
|
||||
}
|
||||
|
||||
int Lua_Mob::GetItemStat(uint32 itemid, const char* identifier) {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->GetItemStat(itemid, identifier);
|
||||
}
|
||||
|
||||
Lua_StatBonuses Lua_Mob::GetItemBonuses()
|
||||
{
|
||||
Lua_Safe_Call_Class(Lua_StatBonuses);
|
||||
@@ -2202,6 +2222,7 @@ luabind::scope lua_register_mob() {
|
||||
.def("DoAnim", (void(Lua_Mob::*)(int,int,bool,int))&Lua_Mob::DoAnim)
|
||||
.def("ChangeSize", (void(Lua_Mob::*)(double))&Lua_Mob::ChangeSize)
|
||||
.def("ChangeSize", (void(Lua_Mob::*)(double,bool))&Lua_Mob::ChangeSize)
|
||||
.def("RandomizeFeatures", (void(Lua_Mob::*)(bool,bool))&Lua_Mob::RandomizeFeatures)
|
||||
.def("GMMove", (void(Lua_Mob::*)(double,double,double))&Lua_Mob::GMMove)
|
||||
.def("GMMove", (void(Lua_Mob::*)(double,double,double,double))&Lua_Mob::GMMove)
|
||||
.def("GMMove", (void(Lua_Mob::*)(double,double,double,double,bool))&Lua_Mob::GMMove)
|
||||
@@ -2212,6 +2233,8 @@ luabind::scope lua_register_mob() {
|
||||
.def("IsInvisible", (bool(Lua_Mob::*)(Lua_Mob))&Lua_Mob::IsInvisible)
|
||||
.def("SetInvisible", &Lua_Mob::SetInvisible)
|
||||
.def("FindBuff", &Lua_Mob::FindBuff)
|
||||
.def("FindBuffBySlot", (uint16(Lua_Mob::*)(int))&Lua_Mob::FindBuffBySlot)
|
||||
.def("BuffCount", &Lua_Mob::BuffCount)
|
||||
.def("FindType", (bool(Lua_Mob::*)(int))&Lua_Mob::FindType)
|
||||
.def("FindType", (bool(Lua_Mob::*)(int,bool))&Lua_Mob::FindType)
|
||||
.def("FindType", (bool(Lua_Mob::*)(int,bool,int))&Lua_Mob::FindType)
|
||||
@@ -2242,6 +2265,7 @@ luabind::scope lua_register_mob() {
|
||||
.def("IsWarriorClass", &Lua_Mob::IsWarriorClass)
|
||||
.def("GetHP", &Lua_Mob::GetHP)
|
||||
.def("GetMaxHP", &Lua_Mob::GetMaxHP)
|
||||
.def("GetItemStat", (int(Lua_Mob::*)(uint32,const char*))&Lua_Mob::GetItemStat)
|
||||
.def("GetItemHPBonuses", &Lua_Mob::GetItemHPBonuses)
|
||||
.def("GetSpellHPBonuses", &Lua_Mob::GetSpellHPBonuses)
|
||||
.def("GetWalkspeed", &Lua_Mob::GetWalkspeed)
|
||||
|
||||
@@ -71,6 +71,7 @@ public:
|
||||
void DoAnim(int anim_num, int type, bool ackreq, int filter);
|
||||
void ChangeSize(double in_size);
|
||||
void ChangeSize(double in_size, bool no_restriction);
|
||||
void RandomizeFeatures(bool send_illusion, bool save_variables);
|
||||
void GMMove(double x, double y, double z);
|
||||
void GMMove(double x, double y, double z, double heading);
|
||||
void GMMove(double x, double y, double z, double heading, bool send_update);
|
||||
@@ -81,6 +82,8 @@ public:
|
||||
bool IsInvisible(Lua_Mob other);
|
||||
void SetInvisible(int state);
|
||||
bool FindBuff(int spell_id);
|
||||
uint16 FindBuffBySlot(int slot);
|
||||
uint32 BuffCount();
|
||||
bool FindType(int type);
|
||||
bool FindType(int type, bool offensive);
|
||||
bool FindType(int type, bool offensive, int threshold);
|
||||
@@ -401,6 +404,7 @@ public:
|
||||
bool IsAmnesiad();
|
||||
int32 GetMeleeMitigation();
|
||||
int GetWeaponDamageBonus(Lua_Item weapon, bool offhand);
|
||||
int GetItemStat(uint32 itemid, const char* identifier);
|
||||
Lua_StatBonuses GetItemBonuses();
|
||||
Lua_StatBonuses GetSpellBonuses();
|
||||
Lua_StatBonuses GetAABonuses();
|
||||
|
||||
+15
-15
@@ -66,7 +66,7 @@ Merc::Merc(const NPCType* d, float x, float y, float z, float heading)
|
||||
memset(equipment, 0, sizeof(equipment));
|
||||
|
||||
SetMercID(0);
|
||||
SetStance(MercStanceBalanced);
|
||||
SetStance(EQEmu::constants::stanceBalanced);
|
||||
rest_timer.Disable();
|
||||
|
||||
if (GetClass() == ROGUE)
|
||||
@@ -1908,7 +1908,7 @@ bool Merc::AI_IdleCastCheck() {
|
||||
|
||||
bool EntityList::Merc_AICheckCloseBeneficialSpells(Merc* caster, uint8 iChance, float iRange, uint32 iSpellTypes) {
|
||||
|
||||
if((iSpellTypes&SpellTypes_Detrimental) != 0) {
|
||||
if((iSpellTypes & SPELL_TYPES_DETRIMENTAL) != 0) {
|
||||
//according to live, you can buff and heal through walls...
|
||||
//now with PCs, this only applies if you can TARGET the target, but
|
||||
// according to Rogean, Live NPCs will just cast through walls/floors, no problem..
|
||||
@@ -3669,13 +3669,13 @@ MercSpell Merc::GetBestMercSpellForAENuke(Merc* caster, Mob* tar) {
|
||||
|
||||
switch(caster->GetStance())
|
||||
{
|
||||
case MercStanceBurnAE:
|
||||
case EQEmu::constants::stanceBurnAE:
|
||||
initialCastChance = 50;
|
||||
break;
|
||||
case MercStanceBalanced:
|
||||
case EQEmu::constants::stanceBalanced:
|
||||
initialCastChance = 25;
|
||||
break;
|
||||
case MercStanceBurn:
|
||||
case EQEmu::constants::stanceBurn:
|
||||
initialCastChance = 0;
|
||||
break;
|
||||
}
|
||||
@@ -3717,11 +3717,11 @@ MercSpell Merc::GetBestMercSpellForTargetedAENuke(Merc* caster, Mob* tar) {
|
||||
|
||||
switch(caster->GetStance())
|
||||
{
|
||||
case MercStanceBurnAE:
|
||||
case EQEmu::constants::stanceBurnAE:
|
||||
numTargetsCheck = 1;
|
||||
break;
|
||||
case MercStanceBalanced:
|
||||
case MercStanceBurn:
|
||||
case EQEmu::constants::stanceBalanced:
|
||||
case EQEmu::constants::stanceBurn:
|
||||
numTargetsCheck = 2;
|
||||
break;
|
||||
}
|
||||
@@ -3769,11 +3769,11 @@ MercSpell Merc::GetBestMercSpellForPBAENuke(Merc* caster, Mob* tar) {
|
||||
|
||||
switch(caster->GetStance())
|
||||
{
|
||||
case MercStanceBurnAE:
|
||||
case EQEmu::constants::stanceBurnAE:
|
||||
numTargetsCheck = 2;
|
||||
break;
|
||||
case MercStanceBalanced:
|
||||
case MercStanceBurn:
|
||||
case EQEmu::constants::stanceBalanced:
|
||||
case EQEmu::constants::stanceBurn:
|
||||
numTargetsCheck = 3;
|
||||
break;
|
||||
}
|
||||
@@ -3820,11 +3820,11 @@ MercSpell Merc::GetBestMercSpellForAERainNuke(Merc* caster, Mob* tar) {
|
||||
|
||||
switch(caster->GetStance())
|
||||
{
|
||||
case MercStanceBurnAE:
|
||||
case EQEmu::constants::stanceBurnAE:
|
||||
numTargetsCheck = 1;
|
||||
break;
|
||||
case MercStanceBalanced:
|
||||
case MercStanceBurn:
|
||||
case EQEmu::constants::stanceBalanced:
|
||||
case EQEmu::constants::stanceBurn:
|
||||
numTargetsCheck = 2;
|
||||
break;
|
||||
}
|
||||
@@ -5649,7 +5649,7 @@ void Client::SpawnMerc(Merc* merc, bool setMaxStats) {
|
||||
merc->SetSuspended(false);
|
||||
SetMerc(merc);
|
||||
merc->Unsuspend(setMaxStats);
|
||||
merc->SetStance(GetMercInfo().Stance);
|
||||
merc->SetStance((EQEmu::constants::StanceType)GetMercInfo().Stance);
|
||||
|
||||
Log(Logs::General, Logs::Mercenaries, "SpawnMerc Success for %s.", GetName());
|
||||
|
||||
|
||||
+3
-15
@@ -30,18 +30,6 @@ namespace EQEmu
|
||||
|
||||
const int MercAISpellRange = 100; // TODO: Write a method that calcs what the merc's spell range is based on spell, equipment, AA, whatever and replace this
|
||||
|
||||
enum MercStanceType {
|
||||
MercStancePassive = 1,
|
||||
MercStanceBalanced,
|
||||
MercStanceEfficient,
|
||||
MercStanceReactive,
|
||||
MercStanceAggressive,
|
||||
MercStanceAssist,
|
||||
MercStanceBurn,
|
||||
MercStanceEfficient2,
|
||||
MercStanceBurnAE
|
||||
};
|
||||
|
||||
struct MercSpell {
|
||||
uint16 spellid; // <= 0 = no spell
|
||||
uint32 type; // 0 = never, must be one (and only one) of the defined values
|
||||
@@ -175,7 +163,7 @@ public:
|
||||
uint8 GetTierID() { return _TierID; }
|
||||
uint32 GetCostFormula() { return _CostFormula; }
|
||||
uint32 GetMercNameType() { return _NameType; }
|
||||
uint32 GetStance() { return _currentStance; }
|
||||
EQEmu::constants::StanceType GetStance() { return _currentStance; }
|
||||
int GetHatedCount() { return _hatedCount; }
|
||||
|
||||
inline const uint8 GetClientVersion() const { return _OwnerClientVersion; }
|
||||
@@ -265,7 +253,7 @@ public:
|
||||
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 SetStance( EQEmu::constants::StanceType stance ) { _currentStance = stance; }
|
||||
void SetHatedCount( int count ) { _hatedCount = count; }
|
||||
|
||||
void Sit();
|
||||
@@ -385,7 +373,7 @@ private:
|
||||
uint8 _CostFormula;
|
||||
uint8 _NameType;
|
||||
uint8 _OwnerClientVersion;
|
||||
uint32 _currentStance;
|
||||
EQEmu::constants::StanceType _currentStance;
|
||||
|
||||
EQEmu::InventoryProfile m_inv;
|
||||
int32 max_end;
|
||||
|
||||
+96
-161
@@ -92,7 +92,8 @@ Mob::Mob(
|
||||
uint8 in_bracertexture,
|
||||
uint8 in_handtexture,
|
||||
uint8 in_legtexture,
|
||||
uint8 in_feettexture
|
||||
uint8 in_feettexture,
|
||||
uint16 in_usemodel
|
||||
) :
|
||||
attack_timer(2000),
|
||||
attack_dw_timer(2000),
|
||||
@@ -147,6 +148,7 @@ Mob::Mob(
|
||||
race = in_race;
|
||||
base_gender = in_gender;
|
||||
base_race = in_race;
|
||||
use_model = in_usemodel;
|
||||
class_ = in_class;
|
||||
bodytype = in_bodytype;
|
||||
orig_bodytype = in_bodytype;
|
||||
@@ -1112,7 +1114,7 @@ void Mob::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho)
|
||||
ns->spawn.spawnId = GetID();
|
||||
ns->spawn.curHp = static_cast<uint8>(GetHPRatio());
|
||||
ns->spawn.max_hp = 100; //this field needs a better name
|
||||
ns->spawn.race = race;
|
||||
ns->spawn.race = (use_model) ? use_model : race;
|
||||
ns->spawn.runspeed = runspeed;
|
||||
ns->spawn.walkspeed = walkspeed;
|
||||
ns->spawn.class_ = class_;
|
||||
@@ -1553,7 +1555,7 @@ void Mob::ShowStats(Client* client)
|
||||
}
|
||||
}
|
||||
else {
|
||||
client->Message(0, " Level: %i AC: %i Class: %i Size: %1.1f Haste: %i", GetLevel(), GetAC(), GetClass(), GetSize(), GetHaste());
|
||||
client->Message(0, " Level: %i AC: %i Class: %i Size: %1.1f Haste: %i", GetLevel(), ACSum(), GetClass(), GetSize(), GetHaste());
|
||||
client->Message(0, " HP: %i Max HP: %i",GetHP(), GetMaxHP());
|
||||
client->Message(0, " Mana: %i Max Mana: %i", GetMana(), GetMaxMana());
|
||||
client->Message(0, " Total ATK: %i Worn/Spell ATK (Cap %i): %i", GetATK(), RuleI(Character, ItemATKCap), GetATKBonus());
|
||||
@@ -1692,151 +1694,74 @@ void Mob::SendIllusionPacket(
|
||||
float in_size
|
||||
)
|
||||
{
|
||||
uint8 new_texture = in_texture;
|
||||
uint8 new_helmtexture = in_helmtexture;
|
||||
uint8 new_haircolor;
|
||||
uint8 new_beardcolor;
|
||||
uint8 new_eyecolor1;
|
||||
uint8 new_eyecolor2;
|
||||
uint8 new_hairstyle;
|
||||
uint8 new_luclinface;
|
||||
uint8 new_beard;
|
||||
uint8 new_aa_title;
|
||||
uint32 new_drakkin_heritage;
|
||||
uint32 new_drakkin_tattoo;
|
||||
uint32 new_drakkin_details;
|
||||
|
||||
uint16 BaseRace = GetBaseRace();
|
||||
race = (in_race) ? in_race : GetBaseRace();
|
||||
|
||||
if (in_race == 0) {
|
||||
race = BaseRace;
|
||||
if (in_gender == 0xFF) {
|
||||
gender = GetBaseGender();
|
||||
if (in_gender != 0xFF)
|
||||
{
|
||||
gender = in_gender;
|
||||
}
|
||||
else {
|
||||
gender = in_gender;
|
||||
else
|
||||
{
|
||||
gender = (in_race) ? GetDefaultGender(race, gender) : GetBaseGender();
|
||||
}
|
||||
}
|
||||
else {
|
||||
race = in_race;
|
||||
if (in_gender == 0xFF) {
|
||||
gender = GetDefaultGender(race, gender);
|
||||
|
||||
if (in_texture == 0xFF && !IsPlayerRace(in_race))
|
||||
{
|
||||
new_texture = GetTexture();
|
||||
}
|
||||
else {
|
||||
gender = in_gender;
|
||||
|
||||
if (in_helmtexture == 0xFF && !IsPlayerRace(in_race))
|
||||
{
|
||||
new_helmtexture = GetHelmTexture();
|
||||
}
|
||||
}
|
||||
|
||||
if (in_texture == 0xFF) {
|
||||
if (IsPlayerRace(in_race)) {
|
||||
texture = 0xFF;
|
||||
}
|
||||
else {
|
||||
texture = GetTexture();
|
||||
}
|
||||
}
|
||||
else {
|
||||
texture = in_texture;
|
||||
}
|
||||
|
||||
if (in_helmtexture == 0xFF) {
|
||||
if (IsPlayerRace(in_race)) {
|
||||
helmtexture = 0xFF;
|
||||
}
|
||||
else if (in_texture != 0xFF) {
|
||||
helmtexture = in_texture;
|
||||
}
|
||||
else {
|
||||
helmtexture = GetHelmTexture();
|
||||
}
|
||||
}
|
||||
else {
|
||||
helmtexture = in_helmtexture;
|
||||
}
|
||||
|
||||
if (in_haircolor == 0xFF) {
|
||||
haircolor = GetHairColor();
|
||||
}
|
||||
else {
|
||||
haircolor = in_haircolor;
|
||||
}
|
||||
|
||||
if (in_beardcolor == 0xFF) {
|
||||
beardcolor = GetBeardColor();
|
||||
}
|
||||
else {
|
||||
beardcolor = in_beardcolor;
|
||||
}
|
||||
|
||||
if (in_eyecolor1 == 0xFF) {
|
||||
eyecolor1 = GetEyeColor1();
|
||||
}
|
||||
else {
|
||||
eyecolor1 = in_eyecolor1;
|
||||
}
|
||||
|
||||
if (in_eyecolor2 == 0xFF) {
|
||||
eyecolor2 = GetEyeColor2();
|
||||
}
|
||||
else {
|
||||
eyecolor2 = in_eyecolor2;
|
||||
}
|
||||
|
||||
if (in_hairstyle == 0xFF) {
|
||||
hairstyle = GetHairStyle();
|
||||
}
|
||||
else {
|
||||
hairstyle = in_hairstyle;
|
||||
}
|
||||
|
||||
if (in_luclinface == 0xFF) {
|
||||
luclinface = GetLuclinFace();
|
||||
}
|
||||
else {
|
||||
luclinface = in_luclinface;
|
||||
}
|
||||
|
||||
if (in_beard == 0xFF) {
|
||||
beard = GetBeard();
|
||||
}
|
||||
else {
|
||||
beard = in_beard;
|
||||
}
|
||||
|
||||
aa_title = in_aa_title;
|
||||
|
||||
if (in_drakkin_heritage == 0xFFFFFFFF) {
|
||||
drakkin_heritage = GetDrakkinHeritage();
|
||||
}
|
||||
else {
|
||||
drakkin_heritage = in_drakkin_heritage;
|
||||
}
|
||||
|
||||
if (in_drakkin_tattoo == 0xFFFFFFFF) {
|
||||
drakkin_tattoo = GetDrakkinTattoo();
|
||||
}
|
||||
else {
|
||||
drakkin_tattoo = in_drakkin_tattoo;
|
||||
}
|
||||
|
||||
if (in_drakkin_details == 0xFFFFFFFF) {
|
||||
drakkin_details = GetDrakkinDetails();
|
||||
}
|
||||
else {
|
||||
drakkin_details = in_drakkin_details;
|
||||
}
|
||||
|
||||
if (in_size <= 0.0f) {
|
||||
size = GetSize();
|
||||
}
|
||||
else {
|
||||
size = in_size;
|
||||
}
|
||||
new_haircolor = (in_haircolor == 0xFF) ? GetHairColor() : in_haircolor;
|
||||
new_beardcolor = (in_beardcolor == 0xFF) ? GetBeardColor() : in_beardcolor;
|
||||
new_eyecolor1 = (in_eyecolor1 == 0xFF) ? GetEyeColor1() : in_eyecolor1;
|
||||
new_eyecolor2 = (in_eyecolor2 == 0xFF) ? GetEyeColor2() : in_eyecolor2;
|
||||
new_hairstyle = (in_hairstyle == 0xFF) ? GetHairStyle() : in_hairstyle;
|
||||
new_luclinface = (in_luclinface == 0xFF) ? GetLuclinFace() : in_luclinface;
|
||||
new_beard = (in_beard == 0xFF) ? GetBeard() : in_beard;
|
||||
new_drakkin_heritage =
|
||||
(in_drakkin_heritage == 0xFFFFFFFF) ? GetDrakkinHeritage() : in_drakkin_heritage;
|
||||
new_drakkin_tattoo =
|
||||
(in_drakkin_tattoo == 0xFFFFFFFF) ? GetDrakkinTattoo() : in_drakkin_tattoo;
|
||||
new_drakkin_details =
|
||||
(in_drakkin_details == 0xFFFFFFFF) ? GetDrakkinDetails() : in_drakkin_details;
|
||||
new_aa_title = in_aa_title;
|
||||
size = (in_size <= 0.0f) ? GetSize() : in_size;
|
||||
|
||||
// Reset features to Base from the Player Profile
|
||||
if (IsClient() && in_race == 0) {
|
||||
race = CastToClient()->GetBaseRace();
|
||||
gender = CastToClient()->GetBaseGender();
|
||||
texture = 0xFF;
|
||||
helmtexture = 0xFF;
|
||||
haircolor = CastToClient()->GetBaseHairColor();
|
||||
beardcolor = CastToClient()->GetBaseBeardColor();
|
||||
eyecolor1 = CastToClient()->GetBaseEyeColor();
|
||||
eyecolor2 = CastToClient()->GetBaseEyeColor();
|
||||
hairstyle = CastToClient()->GetBaseHairStyle();
|
||||
luclinface = CastToClient()->GetBaseFace();
|
||||
beard = CastToClient()->GetBaseBeard();
|
||||
aa_title = 0xFF;
|
||||
drakkin_heritage = CastToClient()->GetBaseHeritage();
|
||||
drakkin_tattoo = CastToClient()->GetBaseTattoo();
|
||||
drakkin_details = CastToClient()->GetBaseDetails();
|
||||
race = CastToClient()->GetBaseRace();
|
||||
gender = CastToClient()->GetBaseGender();
|
||||
new_texture = texture = 0xFF;
|
||||
new_helmtexture = helmtexture = 0xFF;
|
||||
new_haircolor = haircolor = CastToClient()->GetBaseHairColor();
|
||||
new_beardcolor = beardcolor = CastToClient()->GetBaseBeardColor();
|
||||
new_eyecolor1 = eyecolor1 = CastToClient()->GetBaseEyeColor();
|
||||
new_eyecolor2 = eyecolor2 = CastToClient()->GetBaseEyeColor();
|
||||
new_hairstyle = hairstyle = CastToClient()->GetBaseHairStyle();
|
||||
new_luclinface = luclinface = CastToClient()->GetBaseFace();
|
||||
new_beard = beard = CastToClient()->GetBaseBeard();
|
||||
new_aa_title = aa_title = 0xFF;
|
||||
new_drakkin_heritage = drakkin_heritage = CastToClient()->GetBaseHeritage();
|
||||
new_drakkin_tattoo = drakkin_tattoo = CastToClient()->GetBaseTattoo();
|
||||
new_drakkin_details = drakkin_details = CastToClient()->GetBaseDetails();
|
||||
switch (race) {
|
||||
case OGRE:
|
||||
size = 9;
|
||||
@@ -1873,18 +1798,18 @@ void Mob::SendIllusionPacket(
|
||||
strcpy(is->charname, GetCleanName());
|
||||
is->race = race;
|
||||
is->gender = gender;
|
||||
is->texture = texture;
|
||||
is->helmtexture = helmtexture;
|
||||
is->haircolor = haircolor;
|
||||
is->beardcolor = beardcolor;
|
||||
is->beard = beard;
|
||||
is->eyecolor1 = eyecolor1;
|
||||
is->eyecolor2 = eyecolor2;
|
||||
is->hairstyle = hairstyle;
|
||||
is->face = luclinface;
|
||||
is->drakkin_heritage = drakkin_heritage;
|
||||
is->drakkin_tattoo = drakkin_tattoo;
|
||||
is->drakkin_details = drakkin_details;
|
||||
is->texture = new_texture;
|
||||
is->helmtexture = new_helmtexture;
|
||||
is->haircolor = new_haircolor;
|
||||
is->beardcolor = new_beardcolor;
|
||||
is->beard = new_beard;
|
||||
is->eyecolor1 = new_eyecolor1;
|
||||
is->eyecolor2 = new_eyecolor2;
|
||||
is->hairstyle = new_hairstyle;
|
||||
is->face = new_luclinface;
|
||||
is->drakkin_heritage = new_drakkin_heritage;
|
||||
is->drakkin_tattoo = new_drakkin_tattoo;
|
||||
is->drakkin_details = new_drakkin_details;
|
||||
is->size = size;
|
||||
|
||||
entity_list.QueueClients(this, outapp);
|
||||
@@ -1898,17 +1823,17 @@ void Mob::SendIllusionPacket(
|
||||
"Illusion: Race = %i, Gender = %i, Texture = %i, HelmTexture = %i, HairColor = %i, BeardColor = %i, EyeColor1 = %i, EyeColor2 = %i, HairStyle = %i, Face = %i, DrakkinHeritage = %i, DrakkinTattoo = %i, DrakkinDetails = %i, Size = %f",
|
||||
race,
|
||||
gender,
|
||||
texture,
|
||||
helmtexture,
|
||||
haircolor,
|
||||
beardcolor,
|
||||
eyecolor1,
|
||||
eyecolor2,
|
||||
hairstyle,
|
||||
luclinface,
|
||||
drakkin_heritage,
|
||||
drakkin_tattoo,
|
||||
drakkin_details,
|
||||
new_texture,
|
||||
new_helmtexture,
|
||||
new_haircolor,
|
||||
new_beardcolor,
|
||||
new_eyecolor1,
|
||||
new_eyecolor2,
|
||||
new_hairstyle,
|
||||
new_luclinface,
|
||||
new_drakkin_heritage,
|
||||
new_drakkin_tattoo,
|
||||
new_drakkin_details,
|
||||
size);
|
||||
}
|
||||
|
||||
@@ -2121,6 +2046,16 @@ bool Mob::IsPlayerRace(uint16 in_race) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint16 Mob::GetFactionRace() {
|
||||
uint16 current_race = GetRace();
|
||||
if (IsPlayerRace(current_race) || current_race == TREE ||
|
||||
current_race == MINOR_ILL_OBJ) {
|
||||
return current_race;
|
||||
}
|
||||
else {
|
||||
return (GetBaseRace());
|
||||
}
|
||||
}
|
||||
|
||||
uint8 Mob::GetDefaultGender(uint16 in_race, uint8 in_gender) {
|
||||
if (Mob::IsPlayerRace(in_race) || in_race == 15 || in_race == 50 || in_race == 57 || in_race == 70 || in_race == 98 || in_race == 118 || in_race == 562) {
|
||||
|
||||
+11
-6
@@ -159,7 +159,8 @@ public:
|
||||
uint8 in_bracertexture,
|
||||
uint8 in_handtexture,
|
||||
uint8 in_legtexture,
|
||||
uint8 in_feettexture
|
||||
uint8 in_feettexture,
|
||||
uint16 in_usemodel
|
||||
);
|
||||
virtual ~Mob();
|
||||
|
||||
@@ -384,6 +385,8 @@ public:
|
||||
void DamageShield(Mob* other, bool spell_ds = false);
|
||||
int32 RuneAbsorb(int32 damage, uint16 type);
|
||||
bool FindBuff(uint16 spellid);
|
||||
uint16 FindBuffBySlot(int slot);
|
||||
uint32 BuffCount();
|
||||
bool FindType(uint16 type, bool bOffensive = false, uint16 threshold = 100);
|
||||
int16 GetBuffSlotFromType(uint16 type);
|
||||
uint16 GetSpellIDFromSlot(uint8 slot);
|
||||
@@ -442,6 +445,7 @@ public:
|
||||
virtual void SetMaxHP() { current_hp = max_hp; }
|
||||
virtual inline uint16 GetBaseRace() const { return base_race; }
|
||||
virtual inline uint8 GetBaseGender() const { return base_gender; }
|
||||
virtual uint16 GetFactionRace();
|
||||
virtual inline uint16 GetDeity() const { return deity; }
|
||||
virtual EQEmu::deity::DeityTypeBit GetDeityBit() { return EQEmu::deity::ConvertDeityTypeToDeityTypeBit((EQEmu::deity::DeityType)deity); }
|
||||
inline uint16 GetRace() const { return race; }
|
||||
@@ -576,8 +580,8 @@ public:
|
||||
virtual void SetMoving(bool move) { moving = move; m_Delta = glm::vec4(); }
|
||||
virtual void GoToBind(uint8 bindnum = 0) { }
|
||||
virtual void Gate(uint8 bindnum = 0);
|
||||
int GetWalkspeed() const { return(_GetWalkSpeed()); }
|
||||
int GetRunspeed() const { return(_GetRunSpeed()); }
|
||||
virtual int GetWalkspeed() const { return(_GetWalkSpeed()); }
|
||||
virtual int GetRunspeed() const { return(_GetRunSpeed()); }
|
||||
int GetBaseRunspeed() const { return base_runspeed; }
|
||||
int GetBaseWalkspeed() const { return base_walkspeed; }
|
||||
int GetBaseFearSpeed() const { return base_fearspeed; }
|
||||
@@ -998,8 +1002,8 @@ public:
|
||||
|
||||
inline bool CheckAggro(Mob* other) {return hate_list.IsEntOnHateList(other);}
|
||||
float CalculateHeadingToTarget(float in_x, float in_y) { return HeadingAngleToMob(in_x, in_y); }
|
||||
void WalkTo(float x, float y, float z);
|
||||
void RunTo(float x, float y, float z);
|
||||
virtual void WalkTo(float x, float y, float z);
|
||||
virtual void RunTo(float x, float y, float z);
|
||||
void NavigateTo(float x, float y, float z);
|
||||
void RotateTo(float new_heading);
|
||||
void RotateToWalking(float new_heading);
|
||||
@@ -1090,7 +1094,7 @@ public:
|
||||
inline glm::vec4 GetCurrentWayPoint() const { return m_CurrentWayPoint; }
|
||||
inline float GetCWPP() const { return(static_cast<float>(cur_wp_pause)); }
|
||||
inline int GetCWP() const { return(cur_wp); }
|
||||
void SetCurrentWP(uint16 waypoint) { cur_wp = waypoint; }
|
||||
void SetCurrentWP(int waypoint) { cur_wp = waypoint; }
|
||||
virtual FACTION_VALUE GetReverseFactionCon(Mob* iOther) { return FACTION_INDIFFERENT; }
|
||||
|
||||
virtual const bool IsUnderwaterOnly() const { return false; }
|
||||
@@ -1279,6 +1283,7 @@ protected:
|
||||
|
||||
uint8 gender;
|
||||
uint16 race;
|
||||
uint16 use_model;
|
||||
uint8 base_gender;
|
||||
uint16 base_race;
|
||||
uint8 class_;
|
||||
|
||||
+44
-19
@@ -379,7 +379,7 @@ bool NPC::AIDoSpellCast(uint8 i, Mob* tar, int32 mana_cost, uint32* oDontDoAgain
|
||||
}
|
||||
|
||||
bool EntityList::AICheckCloseBeneficialSpells(NPC* caster, uint8 iChance, float iRange, uint32 iSpellTypes) {
|
||||
if((iSpellTypes & SpellTypes_Detrimental) != 0) {
|
||||
if((iSpellTypes & SPELL_TYPES_DETRIMENTAL) != 0) {
|
||||
//according to live, you can buff and heal through walls...
|
||||
//now with PCs, this only applies if you can TARGET the target, but
|
||||
// according to Rogean, Live NPCs will just cast through walls/floors, no problem..
|
||||
@@ -447,7 +447,7 @@ void Mob::AI_Init()
|
||||
maxLastFightingDelayMoving = RuleI(NPC, LastFightingDelayMovingMax);
|
||||
|
||||
pDontHealMeBefore = 0;
|
||||
pDontBuffMeBefore = 0;
|
||||
pDontBuffMeBefore = Timer::GetCurrentTime() + 400;
|
||||
pDontDotMeBefore = 0;
|
||||
pDontRootMeBefore = 0;
|
||||
pDontSnareMeBefore = 0;
|
||||
@@ -1574,7 +1574,18 @@ void NPC::AI_DoMovement() {
|
||||
*/
|
||||
if (roambox_distance > 0) {
|
||||
|
||||
if (!IsMoving()) {
|
||||
// Check if we're already moving to a WP
|
||||
// If so, if we're not moving we have arrived and need to set delay
|
||||
|
||||
if (GetCWP() == EQEmu::WaypointStatus::RoamBoxPauseInProgress && !IsMoving()) {
|
||||
// We have arrived
|
||||
time_until_can_move = Timer::GetCurrentTime() + RandomTimer(roambox_min_delay, roambox_delay);
|
||||
SetCurrentWP(0);
|
||||
return;
|
||||
}
|
||||
|
||||
// Set a new destination
|
||||
if (!IsMoving() && time_until_can_move < Timer::GetCurrentTime()) {
|
||||
auto move_x = static_cast<float>(zone->random.Real(-roambox_distance, roambox_distance));
|
||||
auto move_y = static_cast<float>(zone->random.Real(-roambox_distance, roambox_distance));
|
||||
|
||||
@@ -1625,11 +1636,12 @@ void NPC::AI_DoMovement() {
|
||||
}
|
||||
}
|
||||
|
||||
glm::vec3 destination;
|
||||
destination.x = roambox_destination_x;
|
||||
destination.y = roambox_destination_y;
|
||||
destination.z = m_Position.z;
|
||||
roambox_destination_z = zone->zonemap ? zone->zonemap->FindClosestZ(destination, nullptr) + this->GetZOffset() : 0;
|
||||
roambox_destination_z = 0;
|
||||
/*
|
||||
if (zone->zonemap) {
|
||||
roambox_destination_z = FindGroundZ(roambox_destination_x, roambox_destination_y, this->GetZOffset());
|
||||
}
|
||||
*/
|
||||
|
||||
Log(Logs::Detail,
|
||||
Logs::NPCRoamBox,
|
||||
@@ -1642,12 +1654,10 @@ void NPC::AI_DoMovement() {
|
||||
roambox_min_y,
|
||||
roambox_max_y,
|
||||
roambox_destination_y);
|
||||
}
|
||||
Log(Logs::Detail, Logs::NPCRoamBox, "Dest Z is (%f)", roambox_destination_z);
|
||||
|
||||
NavigateTo(roambox_destination_x, roambox_destination_y, roambox_destination_z);
|
||||
|
||||
if (m_Position.x == roambox_destination_x && m_Position.y == roambox_destination_y) {
|
||||
time_until_can_move = Timer::GetCurrentTime() + RandomTimer(roambox_min_delay, roambox_delay);
|
||||
SetCurrentWP(EQEmu::WaypointStatus::RoamBoxPauseInProgress);
|
||||
NavigateTo(roambox_destination_x, roambox_destination_y, roambox_destination_z);
|
||||
}
|
||||
|
||||
return;
|
||||
@@ -1660,7 +1670,7 @@ void NPC::AI_DoMovement() {
|
||||
|
||||
int32 gridno = CastToNPC()->GetGrid();
|
||||
|
||||
if (gridno > 0 || cur_wp == -2) {
|
||||
if (gridno > 0 || cur_wp == EQEmu::WaypointStatus::QuestControlNoGrid) {
|
||||
if (pause_timer_complete == true) { // time to pause at wp is over
|
||||
AI_SetupNextWaypoint();
|
||||
} // endif (pause_timer_complete==true)
|
||||
@@ -1692,7 +1702,7 @@ void NPC::AI_DoMovement() {
|
||||
// as that is where roamer is unset and we don't want
|
||||
// the next trip through to move again based on grid stuff.
|
||||
doMove = false;
|
||||
if (cur_wp == -2) {
|
||||
if (cur_wp == EQEmu::WaypointStatus::QuestControlNoGrid) {
|
||||
AI_SetupNextWaypoint();
|
||||
}
|
||||
|
||||
@@ -1790,9 +1800,8 @@ void NPC::AI_SetupNextWaypoint() {
|
||||
else {
|
||||
pause_timer_complete = false;
|
||||
Log(Logs::Detail, Logs::Pathing, "We are departing waypoint %d.", cur_wp);
|
||||
|
||||
//if we were under quest control (with no grid), we are done now..
|
||||
if (cur_wp == -2) {
|
||||
if (cur_wp == EQEmu::WaypointStatus::QuestControlNoGrid) {
|
||||
Log(Logs::Detail, Logs::Pathing, "Non-grid quest mob has reached its quest ordered waypoint. Leaving pathing mode.");
|
||||
roamer = false;
|
||||
cur_wp = 0;
|
||||
@@ -2427,7 +2436,7 @@ bool NPC::AI_AddNPCSpells(uint32 iDBSpellsID) {
|
||||
}
|
||||
DBnpcspells_Struct* parentlist = database.GetNPCSpells(spell_list->parent_list);
|
||||
#if MobAI_DEBUG_Spells >= 10
|
||||
std::string debug_msg = StringFormat("Loading NPCSpells onto %s: dbspellsid=%u", this->GetName(), iDBSpellsID);
|
||||
std::string debug_msg = StringFormat("Loading NPCSpells onto %s: dbspellsid=%u, level=%u", this->GetName(), iDBSpellsID, this->GetLevel());
|
||||
if (spell_list) {
|
||||
debug_msg.append(StringFormat(" (found, %u), parentlist=%u", spell_list->entries.size(), spell_list->parent_list));
|
||||
if (spell_list->parent_list) {
|
||||
@@ -2441,6 +2450,22 @@ bool NPC::AI_AddNPCSpells(uint32 iDBSpellsID) {
|
||||
debug_msg.append(" (not found)");
|
||||
}
|
||||
Log(Logs::Detail, Logs::AI, "%s", debug_msg.c_str());
|
||||
|
||||
#ifdef MobAI_DEBUG_Spells >= 25
|
||||
if (parentlist) {
|
||||
for (const auto &iter : parentlist->entries) {
|
||||
Log(Logs::Detail, Logs::AI, "(%i) %s", iter.spellid, spells[iter.spellid].name);
|
||||
}
|
||||
}
|
||||
Log(Logs::Detail, Logs::AI, "fin (parent list)");
|
||||
if (spell_list) {
|
||||
for (const auto &iter : spell_list->entries) {
|
||||
Log(Logs::Detail, Logs::AI, "(%i) %s", iter.spellid, spells[iter.spellid].name);
|
||||
}
|
||||
}
|
||||
Log(Logs::Detail, Logs::AI, "fin (spell list)");
|
||||
#endif
|
||||
|
||||
#endif
|
||||
uint16 attack_proc_spell = -1;
|
||||
int8 proc_chance = 3;
|
||||
@@ -2813,7 +2838,7 @@ DBnpcspells_Struct *ZoneDatabase::GetNPCSpells(uint32 iDBSpellsID)
|
||||
entry.max_hp = atoi(row[8]);
|
||||
|
||||
// some spell types don't make much since to be priority 0, so fix that
|
||||
if (!(entry.type & SpellTypes_Innate) && entry.priority == 0)
|
||||
if (!(entry.type & SPELL_TYPES_INNATE) && entry.priority == 0)
|
||||
entry.priority = 1;
|
||||
|
||||
if (row[9])
|
||||
|
||||
+2
-2
@@ -189,11 +189,11 @@ inline std::string GetMobAttributeByString(Mob *mob, const std::string &attribut
|
||||
}
|
||||
|
||||
if (attribute == "cor") {
|
||||
return std::to_string(mob->GetCorrup());
|
||||
return commify(std::to_string(mob->GetCorrup())) + scaling_modified;
|
||||
}
|
||||
|
||||
if (attribute == "phy") {
|
||||
return std::to_string(mob->GetPhR());
|
||||
return commify(std::to_string(mob->GetPhR())) + scaling_modified;
|
||||
}
|
||||
|
||||
if (attribute == "name") {
|
||||
|
||||
@@ -671,24 +671,27 @@ void MobMovementManager::SendCommandToClients(Mob *m, float dx, float dy, float
|
||||
}
|
||||
}
|
||||
else {
|
||||
float short_range = RuleR(Pathing, ShortMovementUpdateRange);
|
||||
float long_range = zone->GetMaxMovementUpdateRange();
|
||||
|
||||
for (auto &c : _impl->Clients) {
|
||||
float dist = c->CalculateDistance(m->GetX(), m->GetY(), m->GetZ());
|
||||
|
||||
bool match = false;
|
||||
if (range & ClientRangeClose) {
|
||||
if (dist < 250.0f) {
|
||||
if (dist < short_range) {
|
||||
match = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!match && range & ClientRangeMedium) {
|
||||
if (dist >= 250.0f && dist < 1500.0f) {
|
||||
if (dist >= short_range && dist < long_range) {
|
||||
match = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!match && range & ClientRangeLong) {
|
||||
if (dist >= 1500.0f) {
|
||||
if (dist >= long_range) {
|
||||
match = true;
|
||||
}
|
||||
}
|
||||
@@ -759,7 +762,7 @@ void MobMovementManager::FillCommandStruct(PlayerPositionUpdateServer_Struct *sp
|
||||
spu->delta_y = FloatToEQ13(dy);
|
||||
spu->delta_z = FloatToEQ13(dz);
|
||||
spu->delta_heading = FloatToEQ10(dh);
|
||||
spu->animation = anim;
|
||||
spu->animation = (m->IsBot() ? (int)((float)anim / 1.785714f) : anim);
|
||||
}
|
||||
|
||||
void MobMovementManager::UpdatePath(Mob *who, float x, float y, float z, MobMovementMode mode)
|
||||
|
||||
+44
-20
@@ -32,6 +32,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#include "../common/eq_stream_ident.h"
|
||||
#include "../common/patches/patches.h"
|
||||
#include "../common/rulesys.h"
|
||||
#include "../common/profanity_manager.h"
|
||||
#include "../common/misc_functions.h"
|
||||
#include "../common/string_util.h"
|
||||
#include "../common/platform.h"
|
||||
@@ -41,7 +42,9 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#include "../common/eqemu_exception.h"
|
||||
#include "../common/spdat.h"
|
||||
#include "../common/eqemu_logsys.h"
|
||||
#include "../common/eqemu_logsys_fmt.h"
|
||||
|
||||
#include "api_service.h"
|
||||
#include "zone_config.h"
|
||||
#include "masterentity.h"
|
||||
#include "worldserver.h"
|
||||
@@ -51,7 +54,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#include "command.h"
|
||||
#ifdef BOTS
|
||||
#include "bot_command.h"
|
||||
#include "bot_database.h"
|
||||
#endif
|
||||
#include "zone_config.h"
|
||||
#include "titles.h"
|
||||
@@ -66,6 +68,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#include "../common/event/event_loop.h"
|
||||
#include "../common/event/timer.h"
|
||||
#include "../common/net/eqstream.h"
|
||||
#include "../common/net/servertalk_server.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
@@ -234,20 +237,8 @@ int main(int argc, char** argv) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef BOTS
|
||||
if (!botdb.Connect(
|
||||
Config->DatabaseHost.c_str(),
|
||||
Config->DatabaseUsername.c_str(),
|
||||
Config->DatabasePassword.c_str(),
|
||||
Config->DatabaseDB.c_str(),
|
||||
Config->DatabasePort)) {
|
||||
Log(Logs::General, Logs::Error, "Cannot continue without a bots database connection.");
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Register Log System and Settings */
|
||||
LogSys.OnLogHookCallBackZone(&Zone::GMSayHookCallBackProcess);
|
||||
LogSys.SetGMSayHandler(&Zone::GMSayHookCallBackProcess);
|
||||
database.LoadLogSettings(LogSys.log_settings);
|
||||
LogSys.StartFileLogs();
|
||||
|
||||
@@ -350,6 +341,10 @@ int main(int argc, char** argv) {
|
||||
Log(Logs::General, Logs::Zone_Server, "Loading corpse timers");
|
||||
database.GetDecayTimes(npcCorpseDecayTimes);
|
||||
|
||||
Log(Logs::General, Logs::Zone_Server, "Loading profanity list");
|
||||
if (!EQEmu::ProfanityManager::LoadProfanityList(&database))
|
||||
Log(Logs::General, Logs::Error, "Loading profanity list FAILED!");
|
||||
|
||||
Log(Logs::General, Logs::Zone_Server, "Loading commands");
|
||||
int retval = command_init();
|
||||
if (retval<0)
|
||||
@@ -388,7 +383,7 @@ int main(int argc, char** argv) {
|
||||
Log(Logs::General, Logs::Zone_Server, "%d bot commands loaded", botretval);
|
||||
|
||||
Log(Logs::General, Logs::Zone_Server, "Loading bot spell casting chances");
|
||||
if (!botdb.LoadBotSpellCastingChances())
|
||||
if (!database.botdb.LoadBotSpellCastingChances())
|
||||
Log(Logs::General, Logs::Error, "Bot spell casting chances loading FAILED");
|
||||
#endif
|
||||
|
||||
@@ -441,34 +436,63 @@ int main(int argc, char** argv) {
|
||||
Log(Logs::Detail, Logs::None, "Main thread running with thread id %d", pthread_self());
|
||||
#endif
|
||||
|
||||
bool worldwasconnected = worldserver.Connected();
|
||||
bool eqsf_open = false;
|
||||
bool websocker_server_opened = false;
|
||||
|
||||
Timer quest_timers(100);
|
||||
UpdateWindowTitle();
|
||||
bool worldwasconnected = worldserver.Connected();
|
||||
std::shared_ptr<EQStreamInterface> eqss;
|
||||
EQStreamInterface *eqsi;
|
||||
bool eqsf_open = false;
|
||||
std::unique_ptr<EQ::Net::EQStreamManager> eqsm;
|
||||
std::chrono::time_point<std::chrono::system_clock> frame_prev = std::chrono::system_clock::now();
|
||||
std::unique_ptr<EQ::Net::WebsocketServer> ws_server;
|
||||
|
||||
auto loop_fn = [&](EQ::Timer* t) {
|
||||
//Advance the timer to our current point in time
|
||||
Timer::SetCurrentTime();
|
||||
|
||||
//Calculate frame time
|
||||
/**
|
||||
* Calculate frame time
|
||||
*/
|
||||
std::chrono::time_point<std::chrono::system_clock> frame_now = std::chrono::system_clock::now();
|
||||
frame_time = std::chrono::duration_cast<std::chrono::duration<double>>(frame_now - frame_prev).count();
|
||||
frame_prev = frame_now;
|
||||
|
||||
/**
|
||||
* Telnet server
|
||||
*/
|
||||
if (!websocker_server_opened && Config->ZonePort != 0) {
|
||||
Log(
|
||||
Logs::General,
|
||||
Logs::Zone_Server,
|
||||
"Websocket Server listener started (%s:%u).",
|
||||
Config->TelnetIP.c_str(),
|
||||
Config->ZonePort
|
||||
);
|
||||
ws_server.reset(new EQ::Net::WebsocketServer(Config->TelnetIP, Config->ZonePort));
|
||||
RegisterApiService(ws_server);
|
||||
websocker_server_opened = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* EQStreamManager
|
||||
*/
|
||||
if (!eqsf_open && Config->ZonePort != 0) {
|
||||
Log(Logs::General, Logs::Zone_Server, "Starting EQ Network server on port %d", Config->ZonePort);
|
||||
|
||||
EQ::Net::EQStreamManagerOptions opts(Config->ZonePort, false, true);
|
||||
EQStreamManagerInterfaceOptions opts(Config->ZonePort, false, RuleB(Network, CompressZoneStream));
|
||||
opts.daybreak_options.resend_delay_ms = RuleI(Network, ResendDelayBaseMS);
|
||||
opts.daybreak_options.resend_delay_factor = RuleR(Network, ResendDelayFactor);
|
||||
opts.daybreak_options.resend_delay_min = RuleI(Network, ResendDelayMinMS);
|
||||
opts.daybreak_options.resend_delay_max = RuleI(Network, ResendDelayMaxMS);
|
||||
opts.daybreak_options.outgoing_data_rate = RuleR(Network, ClientDataRate);
|
||||
eqsm.reset(new EQ::Net::EQStreamManager(opts));
|
||||
eqsf_open = true;
|
||||
|
||||
eqsm->OnNewConnection([&stream_identifier](std::shared_ptr<EQ::Net::EQStream> stream) {
|
||||
stream_identifier.AddStream(stream);
|
||||
LogF(Logs::Detail, Logs::World_Server, "New connection from IP {0}:{1}", stream->RemoteEndpoint(), ntohs(stream->GetRemotePort()));
|
||||
LogF(Logs::Detail, Logs::World_Server, "New connection from IP {0}:{1}", stream->GetRemoteIP(), ntohs(stream->GetRemotePort()));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
+11
-1
@@ -112,7 +112,8 @@ NPC::NPC(const NPCType *npc_type_data, Spawn2 *in_respawn, const glm::vec4 &posi
|
||||
npc_type_data->bracertexture,
|
||||
npc_type_data->handtexture,
|
||||
npc_type_data->legtexture,
|
||||
npc_type_data->feettexture
|
||||
npc_type_data->feettexture,
|
||||
npc_type_data->use_model
|
||||
),
|
||||
attacked_timer(CombatEventTimer_expire),
|
||||
swarm_timer(100),
|
||||
@@ -238,6 +239,7 @@ NPC::NPC(const NPCType *npc_type_data, Spawn2 *in_respawn, const glm::vec4 &posi
|
||||
p_depop = false;
|
||||
loottable_id = npc_type_data->loottable_id;
|
||||
skip_global_loot = npc_type_data->skip_global_loot;
|
||||
skip_auto_scale = npc_type_data->skip_auto_scale;
|
||||
rare_spawn = npc_type_data->rare_spawn;
|
||||
no_target_hotkey = npc_type_data->no_target_hotkey;
|
||||
primary_faction = 0;
|
||||
@@ -2213,6 +2215,14 @@ void NPC::ModifyNPCStat(const char *identifier, const char *new_value)
|
||||
CR = atoi(val.c_str());
|
||||
return;
|
||||
}
|
||||
else if (id == "cor") {
|
||||
Corrup = atoi(val.c_str());
|
||||
return;
|
||||
}
|
||||
else if (id == "phr") {
|
||||
PhR = atoi(val.c_str());
|
||||
return;
|
||||
}
|
||||
else if (id == "pr") {
|
||||
PR = atoi(val.c_str());
|
||||
return;
|
||||
|
||||
@@ -468,6 +468,7 @@ public:
|
||||
|
||||
virtual int GetStuckBehavior() const { return NPCTypedata_ours ? NPCTypedata_ours->stuck_behavior : NPCTypedata->stuck_behavior; }
|
||||
|
||||
inline bool IsSkipAutoScale() const { return skip_auto_scale; }
|
||||
|
||||
protected:
|
||||
|
||||
@@ -612,6 +613,7 @@ protected:
|
||||
private:
|
||||
uint32 loottable_id;
|
||||
bool skip_global_loot;
|
||||
bool skip_auto_scale;
|
||||
bool p_depop;
|
||||
};
|
||||
|
||||
|
||||
+13
-10
@@ -26,6 +26,9 @@
|
||||
*/
|
||||
void NpcScaleManager::ScaleNPC(NPC * npc)
|
||||
{
|
||||
if (npc->IsSkipAutoScale())
|
||||
return;
|
||||
|
||||
int8 npc_type = GetNPCScalingType(npc);
|
||||
int npc_level = npc->GetLevel();
|
||||
bool is_auto_scaled = IsAutoScaled(npc);
|
||||
@@ -42,7 +45,7 @@ void NpcScaleManager::ScaleNPC(NPC * npc)
|
||||
return;
|
||||
}
|
||||
|
||||
if (npc->GetAC() == 0) {
|
||||
if (npc->GetAC() == 0 && is_auto_scaled) {
|
||||
npc->ModifyNPCStat("ac", std::to_string(scale_data.ac).c_str());
|
||||
}
|
||||
if (npc->GetMaxHP() == 0) {
|
||||
@@ -94,11 +97,11 @@ void NpcScaleManager::ScaleNPC(NPC * npc)
|
||||
if (npc->GetDR() == 0) {
|
||||
npc->ModifyNPCStat("dr", std::to_string(scale_data.disease_resist).c_str());
|
||||
}
|
||||
if (npc->GetCorrup() == 0) {
|
||||
npc->ModifyNPCStat("cr", std::to_string(scale_data.corruption_resist).c_str());
|
||||
if (npc->GetCorrup() == 0 && is_auto_scaled) {
|
||||
npc->ModifyNPCStat("cor", std::to_string(scale_data.corruption_resist).c_str());
|
||||
}
|
||||
if (npc->GetPhR() == 0) {
|
||||
npc->ModifyNPCStat("pr", std::to_string(scale_data.physical_resist).c_str());
|
||||
if (npc->GetPhR() == 0 && is_auto_scaled) {
|
||||
npc->ModifyNPCStat("phr", std::to_string(scale_data.physical_resist).c_str());
|
||||
}
|
||||
if (npc->GetMinDMG() == 0 && npc->GetMaxDMG() == 0) {
|
||||
int min_dmg = scale_data.min_dmg;
|
||||
@@ -416,14 +419,14 @@ int8 NpcScaleManager::GetNPCScalingType(NPC *&npc)
|
||||
{
|
||||
std::string npc_name = npc->GetName();
|
||||
|
||||
if (npc->IsRareSpawn() || npc_name.find('#') != std::string::npos || isupper(npc_name[0])) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (npc->IsRaidTarget()) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (npc->IsRareSpawn() || npc_name.find('#') != std::string::npos || isupper(npc_name[0])) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -621,4 +624,4 @@ bool NpcScaleManager::ApplyGlobalBaseScalingToNPCDynamically(NPC *&npc)
|
||||
auto results = database.QueryDatabase(query);
|
||||
|
||||
return results.Success();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ glm::mat4 CreateScaleMatrix(float sx, float sy, float sz) {
|
||||
return scale;
|
||||
}
|
||||
|
||||
OrientedBoundingBox::OrientedBoundingBox(glm::vec3 pos, glm::vec3 rot, glm::vec3 scale, glm::vec3 extents) {
|
||||
OrientedBoundingBox::OrientedBoundingBox(const glm::vec3 &pos, const glm::vec3 &rot, const glm::vec3 &scale, const glm::vec3 &extents) {
|
||||
min_x = -extents.x;
|
||||
max_x = extents.x;
|
||||
|
||||
@@ -81,7 +81,7 @@ OrientedBoundingBox::OrientedBoundingBox(glm::vec3 pos, glm::vec3 rot, glm::vec3
|
||||
inverted_transformation = glm::inverse(transformation);
|
||||
}
|
||||
|
||||
bool OrientedBoundingBox::ContainsPoint(glm::vec3 p) const {
|
||||
bool OrientedBoundingBox::ContainsPoint(const glm::vec3 &p) const {
|
||||
glm::vec4 pt(p.x, p.y, p.z, 1);
|
||||
glm::vec4 box_space_p = inverted_transformation * pt;
|
||||
|
||||
|
||||
@@ -8,10 +8,10 @@ class OrientedBoundingBox
|
||||
{
|
||||
public:
|
||||
OrientedBoundingBox() { }
|
||||
OrientedBoundingBox(glm::vec3 pos, glm::vec3 rot, glm::vec3 scale, glm::vec3 extents);
|
||||
OrientedBoundingBox(const glm::vec3 &pos, const glm::vec3 &rot, const glm::vec3 &scale, const glm::vec3 &extents);
|
||||
~OrientedBoundingBox() { }
|
||||
|
||||
bool ContainsPoint(glm::vec3 p) const;
|
||||
bool ContainsPoint(const glm::vec3 &p) const;
|
||||
|
||||
glm::mat4& GetTransformation() { return transformation; }
|
||||
glm::mat4& GetInvertedTransformation() { return inverted_transformation; }
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
extern Zone *zone;
|
||||
|
||||
const int MaxNavmeshNodes = 4096;
|
||||
const int MaxNavmeshNodes = 1024;
|
||||
|
||||
struct PathfinderNavmesh::Implementation
|
||||
{
|
||||
@@ -163,7 +163,7 @@ IPathfinder::IPath PathfinderNavmesh::FindPath(const glm::vec3 &start, const glm
|
||||
static const int max_polys = 256;
|
||||
dtPolyRef start_ref;
|
||||
dtPolyRef end_ref;
|
||||
glm::vec3 ext(5.0f, 100.0f, 5.0f);
|
||||
glm::vec3 ext(10.0f, 200.0f, 10.0f);
|
||||
|
||||
m_impl->query->findNearestPoly(¤t_location[0], &ext[0], &filter, &start_ref, 0);
|
||||
m_impl->query->findNearestPoly(&dest_location[0], &ext[0], &filter, &end_ref, 0);
|
||||
|
||||
+18
-15
@@ -1,5 +1,5 @@
|
||||
#include "../common/global_define.h"
|
||||
#include "../common/event/background_task.h"
|
||||
#include "../common/event/task.h"
|
||||
|
||||
#include "client.h"
|
||||
#include "zone.h"
|
||||
@@ -40,53 +40,56 @@ void CullPoints(std::vector<FindPerson_Point> &points) {
|
||||
}
|
||||
|
||||
void Client::SendPathPacket(const std::vector<FindPerson_Point> &points) {
|
||||
EQ::BackgroundTask task([](EQEmu::Any &data) {
|
||||
auto &points = EQEmu::any_cast<std::vector<FindPerson_Point>&>(data);
|
||||
EQEmu::Any data(points);
|
||||
EQ::Task([=](EQ::Task::ResolveFn resolve, EQ::Task::RejectFn reject) {
|
||||
auto points = EQEmu::any_cast<std::vector<FindPerson_Point>>(data);
|
||||
CullPoints(points);
|
||||
}, [this](EQEmu::Any &data) {
|
||||
auto &points = EQEmu::any_cast<std::vector<FindPerson_Point>&>(data);
|
||||
|
||||
resolve(points);
|
||||
})
|
||||
.Then([this](const EQEmu::Any &result) {
|
||||
auto points = EQEmu::any_cast<std::vector<FindPerson_Point>>(result);
|
||||
if (points.size() < 2) {
|
||||
if (Admin() > 10) {
|
||||
Message(MT_System, "Too few points");
|
||||
}
|
||||
|
||||
|
||||
EQApplicationPacket outapp(OP_FindPersonReply, 0);
|
||||
QueuePacket(&outapp);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (points.size() > 36) {
|
||||
if (Admin() > 10) {
|
||||
Message(MT_System, "Too many points %u", points.size());
|
||||
}
|
||||
|
||||
|
||||
EQApplicationPacket outapp(OP_FindPersonReply, 0);
|
||||
QueuePacket(&outapp);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (Admin() > 10) {
|
||||
Message(MT_System, "Total points %u", points.size());
|
||||
}
|
||||
|
||||
|
||||
int len = sizeof(FindPersonResult_Struct) + (points.size() + 1) * sizeof(FindPerson_Point);
|
||||
auto outapp = new EQApplicationPacket(OP_FindPersonReply, len);
|
||||
FindPersonResult_Struct* fpr = (FindPersonResult_Struct*)outapp->pBuffer;
|
||||
|
||||
|
||||
std::vector<FindPerson_Point>::iterator cur, end;
|
||||
cur = points.begin();
|
||||
end = points.end();
|
||||
unsigned int r;
|
||||
for (r = 0; cur != end; ++cur, r++) {
|
||||
fpr->path[r] = *cur;
|
||||
|
||||
|
||||
}
|
||||
//put the last element into the destination field
|
||||
--cur;
|
||||
fpr->path[r] = *cur;
|
||||
fpr->dest = *cur;
|
||||
|
||||
|
||||
FastQueuePacket(&outapp);
|
||||
}, points);
|
||||
})
|
||||
.Run();
|
||||
}
|
||||
|
||||
+123
-12
@@ -1233,15 +1233,17 @@ XS(XS_Client_MovePC) {
|
||||
if (THIS->IsMerc()) {
|
||||
Log(Logs::Detail, Logs::None,
|
||||
"[CLIENT] Perl(XS_Client_MovePC) attempted to process a type Merc reference");
|
||||
} else if (THIS->IsNPC()) {
|
||||
}
|
||||
#ifdef BOTS
|
||||
else if (THIS->IsBot()) {
|
||||
Log(Logs::Detail, Logs::None,
|
||||
"[CLIENT] Perl(XS_Client_MovePC) attempted to process a type Bot reference");
|
||||
}
|
||||
#endif
|
||||
else if (THIS->IsNPC()) {
|
||||
Log(Logs::Detail, Logs::None,
|
||||
"[CLIENT] Perl(XS_Client_MovePC) attempted to process a type NPC reference");
|
||||
}
|
||||
#ifdef BOTS
|
||||
else if (THIS->IsBot()) {
|
||||
Log(Logs::Detail, Logs::None, "[CLIENT] Perl(XS_Client_MovePC) attempted to process a type Bot reference");
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
Log(Logs::Detail, Logs::None,
|
||||
"[CLIENT] Perl(XS_Client_MovePC) attempted to process an Unknown type reference");
|
||||
@@ -1283,15 +1285,17 @@ XS(XS_Client_MovePCInstance) {
|
||||
if (THIS->IsMerc()) {
|
||||
Log(Logs::Detail, Logs::None,
|
||||
"[CLIENT] Perl(XS_Client_MovePCInstance) attempted to process a type Merc reference");
|
||||
} else if (THIS->IsNPC()) {
|
||||
}
|
||||
#ifdef BOTS
|
||||
else if (THIS->IsBot()) {
|
||||
Log(Logs::Detail, Logs::None,
|
||||
"[CLIENT] Perl(XS_Client_MovePCInstance) attempted to process a type Bot reference");
|
||||
}
|
||||
#endif
|
||||
else if (THIS->IsNPC()) {
|
||||
Log(Logs::Detail, Logs::None,
|
||||
"[CLIENT] Perl(XS_Client_MovePCInstance) attempted to process a type NPC reference");
|
||||
}
|
||||
#ifdef BOTS
|
||||
else if (THIS->IsBot()) {
|
||||
Log(Logs::Detail, Logs::None, "[CLIENT] Perl(XS_Client_MovePCInstance) attempted to process a type Bot reference");
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
Log(Logs::Detail, Logs::None,
|
||||
"[CLIENT] Perl(XS_Client_MovePCInstance) attempted to process an Unknown type reference");
|
||||
@@ -2404,6 +2408,57 @@ XS(XS_Client_UnmemSpellAll) {
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
|
||||
XS(XS_Client_FindMemmedSpellBySlot); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_Client_FindMemmedSpellBySlot) {
|
||||
dXSARGS;
|
||||
if (items != 2)
|
||||
Perl_croak(aTHX_ "Usage: Client::FindMemmedSpellBySlot(THIS, int slot)");
|
||||
{
|
||||
Client *THIS;
|
||||
uint16 RETVAL;
|
||||
dXSTARG;
|
||||
int slot = SvIV(ST(1));
|
||||
|
||||
if (sv_derived_from(ST(0), "Client")) {
|
||||
IV tmp = SvIV((SV *) SvRV(ST(0)));
|
||||
THIS = INT2PTR(Client *, tmp);
|
||||
} else
|
||||
Perl_croak(aTHX_ "THIS is not of type Client");
|
||||
if (THIS == nullptr)
|
||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||
|
||||
RETVAL = THIS->FindMemmedSpellBySlot(slot);
|
||||
XSprePUSH;
|
||||
PUSHu((UV) RETVAL);
|
||||
}
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
XS(XS_Client_MemmedCount); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_Client_MemmedCount) {
|
||||
dXSARGS;
|
||||
if (items != 1)
|
||||
Perl_croak(aTHX_ "Usage: Client::MemmedCount(THIS)");
|
||||
{
|
||||
Client *THIS;
|
||||
uint32 RETVAL;
|
||||
dXSTARG;
|
||||
|
||||
if (sv_derived_from(ST(0), "Client")) {
|
||||
IV tmp = SvIV((SV *) SvRV(ST(0)));
|
||||
THIS = INT2PTR(Client *, tmp);
|
||||
} else
|
||||
Perl_croak(aTHX_ "THIS is not of type Client");
|
||||
if (THIS == nullptr)
|
||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||
|
||||
RETVAL = THIS->MemmedCount();
|
||||
XSprePUSH;
|
||||
PUSHu((UV) RETVAL);
|
||||
}
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
XS(XS_Client_ScribeSpell); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_Client_ScribeSpell) {
|
||||
dXSARGS;
|
||||
@@ -2596,6 +2651,32 @@ XS(XS_Client_UntrainDiscAll) {
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
|
||||
XS(XS_Client_IsStanding); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_Client_IsStanding)
|
||||
{
|
||||
dXSARGS;
|
||||
if (items != 1)
|
||||
Perl_croak(aTHX_ "Usage: Client::IsStanding(THIS)");
|
||||
{
|
||||
Client * THIS;
|
||||
bool RETVAL;
|
||||
|
||||
if (sv_derived_from(ST(0), "Client")) {
|
||||
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||
THIS = INT2PTR(Client *,tmp);
|
||||
}
|
||||
else
|
||||
Perl_croak(aTHX_ "THIS is not of type Client");
|
||||
if(THIS == nullptr)
|
||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||
|
||||
RETVAL = THIS->IsStanding();
|
||||
ST(0) = boolSV(RETVAL);
|
||||
sv_2mortal(ST(0));
|
||||
}
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
XS(XS_Client_IsSitting); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_Client_IsSitting) {
|
||||
dXSARGS;
|
||||
@@ -2620,6 +2701,32 @@ XS(XS_Client_IsSitting) {
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
XS(XS_Client_IsCrouching); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_Client_IsCrouching)
|
||||
{
|
||||
dXSARGS;
|
||||
if (items != 1)
|
||||
Perl_croak(aTHX_ "Usage: Client::IsCrouching(THIS)");
|
||||
{
|
||||
Client * THIS;
|
||||
bool RETVAL;
|
||||
|
||||
if (sv_derived_from(ST(0), "Client")) {
|
||||
IV tmp = SvIV((SV*)SvRV(ST(0)));
|
||||
THIS = INT2PTR(Client *,tmp);
|
||||
}
|
||||
else
|
||||
Perl_croak(aTHX_ "THIS is not of type Client");
|
||||
if(THIS == nullptr)
|
||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||
|
||||
RETVAL = THIS->IsCrouching();
|
||||
ST(0) = boolSV(RETVAL);
|
||||
sv_2mortal(ST(0));
|
||||
}
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
XS(XS_Client_IsBecomeNPC); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_Client_IsBecomeNPC) {
|
||||
dXSARGS;
|
||||
@@ -6338,7 +6445,9 @@ XS(boot_Client) {
|
||||
newXSproto(strcpy(buf, "IsLD"), XS_Client_IsLD, file, "$");
|
||||
newXSproto(strcpy(buf, "IsMedding"), XS_Client_IsMedding, file, "$");
|
||||
newXSproto(strcpy(buf, "IsRaidGrouped"), XS_Client_IsRaidGrouped, file, "$");
|
||||
newXSproto(strcpy(buf, "IsStanding"), XS_Client_IsStanding, file, "$");
|
||||
newXSproto(strcpy(buf, "IsSitting"), XS_Client_IsSitting, file, "$");
|
||||
newXSproto(strcpy(buf, "IsCrouching"), XS_Client_IsCrouching, file, "$");
|
||||
newXSproto(strcpy(buf, "IsTaskActive"), XS_Client_IsTaskActive, file, "$$");
|
||||
newXSproto(strcpy(buf, "IsTaskActivityActive"), XS_Client_IsTaskActivityActive, file, "$$$");
|
||||
newXSproto(strcpy(buf, "IsTaskCompleted"), XS_Client_IsTaskCompleted, file, "$$");
|
||||
@@ -6424,6 +6533,8 @@ XS(boot_Client) {
|
||||
newXSproto(strcpy(buf, "UnmemSpell"), XS_Client_UnmemSpell, file, "$$;$");
|
||||
newXSproto(strcpy(buf, "UnmemSpellAll"), XS_Client_UnmemSpellAll, file, "$;$");
|
||||
newXSproto(strcpy(buf, "UnmemSpellBySpellID"), XS_Client_UnmemSpellBySpellID, file, "$$");
|
||||
newXSproto(strcpy(buf, "FindMemmedSpellBySlot"), XS_Client_FindMemmedSpellBySlot, file, "$$");
|
||||
newXSproto(strcpy(buf, "MemmedCount"), XS_Client_MemmedCount, file, "$");
|
||||
newXSproto(strcpy(buf, "UnscribeSpell"), XS_Client_UnscribeSpell, file, "$$;$");
|
||||
newXSproto(strcpy(buf, "UnscribeSpellAll"), XS_Client_UnscribeSpellAll, file, "$;$");
|
||||
newXSproto(strcpy(buf, "UntrainDisc"), XS_Client_UntrainDisc, file, "$$;$");
|
||||
|
||||
+78
-1
@@ -1135,6 +1135,29 @@ XS(XS_Mob_ChangeSize) {
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
|
||||
XS(XS_Mob_RandomizeFeatures); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_Mob_RandomizeFeatures) {
|
||||
dXSARGS;
|
||||
if (items < 2 || items > 3)
|
||||
Perl_croak(aTHX_ "Usage: Mob::RandomizeFeatures(THIS, bool send_illusion, set_variables)");
|
||||
{
|
||||
Mob *THIS;
|
||||
bool send_illusion = (bool) SvNV(ST(1));
|
||||
bool set_variables = (bool) SvNV(ST(2));
|
||||
|
||||
if (sv_derived_from(ST(0), "Mob")) {
|
||||
IV tmp = SvIV((SV *) SvRV(ST(0)));
|
||||
THIS = INT2PTR(Mob *, tmp);
|
||||
} else
|
||||
Perl_croak(aTHX_ "THIS is not of type Mob");
|
||||
if (THIS == nullptr)
|
||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||
|
||||
THIS->RandomizeFeatures(send_illusion, set_variables);
|
||||
}
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
|
||||
XS(XS_Mob_GMMove); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_Mob_GMMove) {
|
||||
dXSARGS;
|
||||
@@ -1274,6 +1297,57 @@ XS(XS_Mob_FindBuff) {
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
XS(XS_Mob_FindBuffBySlot); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_Mob_FindBuffBySlot) {
|
||||
dXSARGS;
|
||||
if (items != 2)
|
||||
Perl_croak(aTHX_ "Usage: Mob::FindBuffBySlot(THIS, int slot)");
|
||||
{
|
||||
Mob *THIS;
|
||||
uint16 RETVAL;
|
||||
dXSTARG;
|
||||
int slot = SvIV(ST(1));
|
||||
|
||||
if (sv_derived_from(ST(0), "Mob")) {
|
||||
IV tmp = SvIV((SV *) SvRV(ST(0)));
|
||||
THIS = INT2PTR(Mob *, tmp);
|
||||
} else
|
||||
Perl_croak(aTHX_ "THIS is not of type Mob");
|
||||
if (THIS == nullptr)
|
||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||
|
||||
RETVAL = THIS->FindBuffBySlot(slot);
|
||||
XSprePUSH;
|
||||
PUSHu((UV) RETVAL);
|
||||
}
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
XS(XS_Mob_BuffCount); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_Mob_BuffCount) {
|
||||
dXSARGS;
|
||||
if (items != 1)
|
||||
Perl_croak(aTHX_ "Usage: Mob::BuffCount(THIS)");
|
||||
{
|
||||
Mob *THIS;
|
||||
uint32 RETVAL;
|
||||
dXSTARG;
|
||||
|
||||
if (sv_derived_from(ST(0), "Mob")) {
|
||||
IV tmp = SvIV((SV *) SvRV(ST(0)));
|
||||
THIS = INT2PTR(Mob *, tmp);
|
||||
} else
|
||||
Perl_croak(aTHX_ "THIS is not of type Mob");
|
||||
if (THIS == nullptr)
|
||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||
|
||||
RETVAL = THIS->BuffCount();
|
||||
XSprePUSH;
|
||||
PUSHu((UV) RETVAL);
|
||||
}
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
XS(XS_Mob_FindType); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_Mob_FindType) {
|
||||
dXSARGS;
|
||||
@@ -6760,7 +6834,7 @@ XS(XS_Mob_SendIllusion) {
|
||||
dXSARGS;
|
||||
if (items < 2 || items > 14)
|
||||
Perl_croak(aTHX_
|
||||
"Usage: Mob::SendIllusion(THIS, uint16 race, [uint8 gender = 0xFF], [uint8 texture = 0xFF], [unit8 helmtexture = 0xFF], [unit8 face = 0xFF], [unit8 hairstyle = 0xFF], [uint8 hair_color = 0xFF], [uint8 beard = 0xFF], [uint8 beard_color = 0xFF], [uint32 drakkin_heritage = 0xFFFFFFFF], [uint32 drakkin_tattoo = 0xFFFFFFFF], [uint32 drakkin_details = 0xFFFFFFFF], [float size = -1])");
|
||||
"Usage: Mob::SendIllusion(THIS, uint16 race, [uint8 gender = 0xFF], [uint8 texture face = 0xFF], [uint8 hairstyle = 0xFF], [uint8 hair_color = 0xFF], [uint8 beard = 0xFF], [uint8 beard_color =FF], [uint32 drakkin_tattoo = 0xFFFFFFFF], [uint32 drakkin_details = 0xFFFFFFFF], [float size = -1])");
|
||||
{
|
||||
Mob *THIS;
|
||||
uint16 race = (uint16) SvIV(ST(1));
|
||||
@@ -8552,11 +8626,14 @@ XS(boot_Mob) {
|
||||
newXSproto(strcpy(buf, "SetHP"), XS_Mob_SetHP, file, "$$");
|
||||
newXSproto(strcpy(buf, "DoAnim"), XS_Mob_DoAnim, file, "$$;$");
|
||||
newXSproto(strcpy(buf, "ChangeSize"), XS_Mob_ChangeSize, file, "$$;$");
|
||||
newXSproto(strcpy(buf, "RandomizeFeatures"), XS_Mob_RandomizeFeatures, file, "$$;$");
|
||||
newXSproto(strcpy(buf, "GMMove"), XS_Mob_GMMove, file, "$$$$;$");
|
||||
newXSproto(strcpy(buf, "HasProcs"), XS_Mob_HasProcs, file, "$");
|
||||
newXSproto(strcpy(buf, "IsInvisible"), XS_Mob_IsInvisible, file, "$;$");
|
||||
newXSproto(strcpy(buf, "SetInvisible"), XS_Mob_SetInvisible, file, "$$");
|
||||
newXSproto(strcpy(buf, "FindBuff"), XS_Mob_FindBuff, file, "$$");
|
||||
newXSproto(strcpy(buf, "FindBuffBySlot"), XS_Mob_FindBuffBySlot, file, "$$");
|
||||
newXSproto(strcpy(buf, "BuffCount"), XS_Mob_BuffCount, file, "$");
|
||||
newXSproto(strcpy(buf, "FindType"), XS_Mob_FindType, file, "$$;$$");
|
||||
newXSproto(strcpy(buf, "GetBuffSlotFromType"), XS_Mob_GetBuffSlotFromType, file, "$$");
|
||||
newXSproto(strcpy(buf, "MakePet"), XS_Mob_MakePet, file, "$$$;$");
|
||||
|
||||
+142
-88
@@ -975,126 +975,181 @@ void QuestManager::permagender(int gender_id) {
|
||||
|
||||
uint16 QuestManager::scribespells(uint8 max_level, uint8 min_level) {
|
||||
QuestManagerCurrentQuestVars();
|
||||
uint16 book_slot, count;
|
||||
uint16 spell_id;
|
||||
int book_slot = initiator->GetNextAvailableSpellBookSlot();
|
||||
int spell_id = 0;
|
||||
int count = 0;
|
||||
|
||||
uint32 char_id = initiator->CharacterID();
|
||||
bool SpellGlobalRule = RuleB(Spells, EnableSpellGlobals);
|
||||
bool SpellBucketRule = RuleB(Spells, EnableSpellBuckets);
|
||||
bool SpellGlobalCheckResult = 0;
|
||||
bool SpellBucketCheckResult = 0;
|
||||
bool SpellGlobalCheckResult = false;
|
||||
bool SpellBucketCheckResult = false;
|
||||
|
||||
for ( ; spell_id < SPDAT_RECORDS && book_slot < EQEmu::spells::SPELLBOOK_SIZE; ++spell_id) {
|
||||
if (book_slot == -1) {
|
||||
initiator->Message(
|
||||
13,
|
||||
"Unable to scribe spell %s (%i) to spellbook: no more spell book slots available.",
|
||||
((spell_id >= 0 && spell_id < SPDAT_RECORDS) ? spells[spell_id].name : "Out-of-range"),
|
||||
spell_id
|
||||
);
|
||||
|
||||
break;
|
||||
}
|
||||
if (spell_id < 0 || spell_id >= SPDAT_RECORDS) {
|
||||
initiator->Message(13, "FATAL ERROR: Spell id out-of-range (id: %i, min: 0, max: %i)", spell_id, SPDAT_RECORDS);
|
||||
return count;
|
||||
}
|
||||
if (book_slot < 0 || book_slot >= EQEmu::spells::SPELLBOOK_SIZE) {
|
||||
initiator->Message(13, "FATAL ERROR: Book slot out-of-range (slot: %i, min: 0, max: %i)", book_slot, EQEmu::spells::SPELLBOOK_SIZE);
|
||||
return count;
|
||||
}
|
||||
|
||||
for(spell_id = 0, book_slot = initiator->GetNextAvailableSpellBookSlot(), count = 0; spell_id < SPDAT_RECORDS && book_slot < EQEmu::spells::SPELLBOOK_SIZE; spell_id++, book_slot = initiator->GetNextAvailableSpellBookSlot(book_slot))
|
||||
{
|
||||
if
|
||||
(
|
||||
spells[spell_id].classes[WARRIOR] != 0 && //check if spell exists
|
||||
spells[spell_id].classes[initiator->GetPP().class_-1] <= max_level && //maximum level
|
||||
spells[spell_id].classes[initiator->GetPP().class_-1] >= min_level && //minimum level
|
||||
spells[spell_id].skill != 52 &&
|
||||
spells[spell_id].effectid[EFFECT_COUNT - 1] != 10
|
||||
)
|
||||
{
|
||||
if (book_slot == -1) //no more book slots
|
||||
while (true) {
|
||||
if (spells[spell_id].classes[WARRIOR] == 0) // check if spell exists
|
||||
break;
|
||||
if(!IsDiscipline(spell_id) && !initiator->HasSpellScribed(spell_id)) { //isn't a discipline & we don't already have it scribed
|
||||
if (spells[spell_id].classes[initiator->GetPP().class_ - 1] > max_level) // maximum level
|
||||
break;
|
||||
if (spells[spell_id].classes[initiator->GetPP().class_ - 1] < min_level) // minimum level
|
||||
break;
|
||||
if (spells[spell_id].skill == 52)
|
||||
break;
|
||||
if (spells[spell_id].effectid[EFFECT_COUNT - 1] == 10)
|
||||
break;
|
||||
|
||||
uint16 spell_id_ = (uint16)spell_id;
|
||||
if ((spell_id_ != spell_id) || (spell_id != spell_id_)) {
|
||||
initiator->Message(13, "FATAL ERROR: Type conversion data loss with spell_id (%i != %u)", spell_id, spell_id_);
|
||||
return count;
|
||||
}
|
||||
|
||||
if (!IsDiscipline(spell_id_) && !initiator->HasSpellScribed(spell_id)) { // isn't a discipline & we don't already have it scribed
|
||||
if (SpellGlobalRule) {
|
||||
// Bool to see if the character has the required QGlobal to scribe it if one exists in the Spell_Globals table
|
||||
SpellGlobalCheckResult = initiator->SpellGlobalCheck(spell_id, char_id);
|
||||
// bool to see if the character has the required QGlobal to scribe it if one exists in the Spell_Globals table
|
||||
SpellGlobalCheckResult = initiator->SpellGlobalCheck(spell_id_, char_id);
|
||||
if (SpellGlobalCheckResult) {
|
||||
initiator->ScribeSpell(spell_id, book_slot);
|
||||
count++;
|
||||
initiator->ScribeSpell(spell_id_, book_slot);
|
||||
++count;
|
||||
}
|
||||
} else if (SpellBucketRule) {
|
||||
SpellBucketCheckResult = initiator->SpellBucketCheck(spell_id, char_id);
|
||||
}
|
||||
else if (SpellBucketRule) {
|
||||
// bool to see if the character has the required bucket to train it if one exists in the spell_buckets table
|
||||
SpellBucketCheckResult = initiator->SpellBucketCheck(spell_id_, char_id);
|
||||
if (SpellBucketCheckResult) {
|
||||
initiator->ScribeSpell(spell_id, book_slot);
|
||||
count++;
|
||||
initiator->ScribeSpell(spell_id_, book_slot);
|
||||
++count;
|
||||
}
|
||||
} else {
|
||||
initiator->ScribeSpell(spell_id, book_slot);
|
||||
count++;
|
||||
}
|
||||
else {
|
||||
initiator->ScribeSpell(spell_id_, book_slot);
|
||||
++count;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
book_slot = initiator->GetNextAvailableSpellBookSlot(book_slot);
|
||||
}
|
||||
return count; //how many spells were scribed successfully
|
||||
|
||||
return count; // how many spells were scribed successfully
|
||||
}
|
||||
|
||||
uint16 QuestManager::traindiscs(uint8 max_level, uint8 min_level) {
|
||||
QuestManagerCurrentQuestVars();
|
||||
uint16 count;
|
||||
uint16 spell_id;
|
||||
int spell_id = 0;
|
||||
int count = 0;
|
||||
|
||||
uint32 char_id = initiator->CharacterID();
|
||||
bool SpellGlobalRule = RuleB(Spells, EnableSpellGlobals);
|
||||
bool SpellBucketRule = RuleB(Spells, EnableSpellBuckets);
|
||||
bool SpellGlobalCheckResult = 0;
|
||||
bool SpellBucketCheckResult = 0;
|
||||
bool SpellGlobalCheckResult = false;
|
||||
bool SpellBucketCheckResult = false;
|
||||
|
||||
for(spell_id = 0, count = 0; spell_id < SPDAT_RECORDS; spell_id++)
|
||||
{
|
||||
if
|
||||
(
|
||||
spells[spell_id].classes[WARRIOR] != 0 && //check if spell exists
|
||||
spells[spell_id].classes[initiator->GetPP().class_-1] <= max_level && //maximum level
|
||||
spells[spell_id].classes[initiator->GetPP().class_-1] >= min_level && //minimum level
|
||||
spells[spell_id].skill != 52 &&
|
||||
( !RuleB(Spells, UseCHAScribeHack) || spells[spell_id].effectid[EFFECT_COUNT - 1] != 10 )
|
||||
)
|
||||
{
|
||||
if(IsDiscipline(spell_id)){
|
||||
//we may want to come up with a function like Client::GetNextAvailableSpellBookSlot() to help speed this up a little
|
||||
for(uint32 r = 0; r < MAX_PP_DISCIPLINES; r++) {
|
||||
if(initiator->GetPP().disciplines.values[r] == spell_id) {
|
||||
initiator->Message(13, "You already know this discipline.");
|
||||
break; //continue the 1st loop
|
||||
}
|
||||
else if(initiator->GetPP().disciplines.values[r] == 0) {
|
||||
if (SpellGlobalRule) {
|
||||
// Bool to see if the character has the required QGlobal to train it if one exists in the Spell_Globals table
|
||||
SpellGlobalCheckResult = initiator->SpellGlobalCheck(spell_id, char_id);
|
||||
if (SpellGlobalCheckResult) {
|
||||
initiator->GetPP().disciplines.values[r] = spell_id;
|
||||
database.SaveCharacterDisc(char_id, r, spell_id);
|
||||
initiator->SendDisciplineUpdate();
|
||||
initiator->Message(0, "You have learned a new discipline!");
|
||||
count++; //success counter
|
||||
}
|
||||
break; //continue the 1st loop
|
||||
} else if (SpellBucketRule) {
|
||||
// Bool to see if the character has the required bucket to train it if one exists in the spell_buckets table
|
||||
SpellBucketCheckResult = initiator->SpellBucketCheck(spell_id, char_id);
|
||||
if (SpellBucketCheckResult) {
|
||||
initiator->GetPP().disciplines.values[r] = spell_id;
|
||||
database.SaveCharacterDisc(char_id, r, spell_id);
|
||||
initiator->SendDisciplineUpdate();
|
||||
initiator->Message(0, "You have learned a new discipline!");
|
||||
count++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
else {
|
||||
initiator->GetPP().disciplines.values[r] = spell_id;
|
||||
database.SaveCharacterDisc(char_id, r, spell_id);
|
||||
initiator->SendDisciplineUpdate();
|
||||
bool change = false;
|
||||
|
||||
for( ; spell_id < SPDAT_RECORDS; ++spell_id) {
|
||||
if (spell_id < 0 || spell_id >= SPDAT_RECORDS) {
|
||||
initiator->Message(13, "FATAL ERROR: Spell id out-of-range (id: %i, min: 0, max: %i)", spell_id, SPDAT_RECORDS);
|
||||
return count;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
if (spells[spell_id].classes[WARRIOR] == 0) // check if spell exists
|
||||
break;
|
||||
if (spells[spell_id].classes[initiator->GetPP().class_ - 1] > max_level) // maximum level
|
||||
break;
|
||||
if (spells[spell_id].classes[initiator->GetPP().class_ - 1] < min_level) // minimum level
|
||||
break;
|
||||
if (spells[spell_id].skill == 52)
|
||||
break;
|
||||
if (RuleB(Spells, UseCHAScribeHack) && spells[spell_id].effectid[EFFECT_COUNT - 1] == 10)
|
||||
break;
|
||||
|
||||
uint16 spell_id_ = (uint16)spell_id;
|
||||
if ((spell_id_ != spell_id) || (spell_id != spell_id_)) {
|
||||
initiator->Message(13, "FATAL ERROR: Type conversion data loss with spell_id (%i != %u)", spell_id, spell_id_);
|
||||
return count;
|
||||
}
|
||||
|
||||
if (!IsDiscipline(spell_id_))
|
||||
break;
|
||||
|
||||
for (uint32 r = 0; r < MAX_PP_DISCIPLINES; r++) {
|
||||
if (initiator->GetPP().disciplines.values[r] == spell_id_) {
|
||||
initiator->Message(13, "You already know this discipline.");
|
||||
break; // continue the 1st loop
|
||||
}
|
||||
else if (initiator->GetPP().disciplines.values[r] == 0) {
|
||||
if (SpellGlobalRule) {
|
||||
// bool to see if the character has the required QGlobal to train it if one exists in the Spell_Globals table
|
||||
SpellGlobalCheckResult = initiator->SpellGlobalCheck(spell_id_, char_id);
|
||||
if (SpellGlobalCheckResult) {
|
||||
initiator->GetPP().disciplines.values[r] = spell_id_;
|
||||
database.SaveCharacterDisc(char_id, r, spell_id_);
|
||||
change = true;
|
||||
initiator->Message(0, "You have learned a new discipline!");
|
||||
count++; //success counter
|
||||
break; //continue the 1st loop
|
||||
++count; // success counter
|
||||
}
|
||||
} //if we get to this point, there's already a discipline in this slot, so we skip it
|
||||
break; // continue the 1st loop
|
||||
}
|
||||
else if (SpellBucketRule) {
|
||||
// bool to see if the character has the required bucket to train it if one exists in the spell_buckets table
|
||||
SpellBucketCheckResult = initiator->SpellBucketCheck(spell_id_, char_id);
|
||||
if (SpellBucketCheckResult) {
|
||||
initiator->GetPP().disciplines.values[r] = spell_id_;
|
||||
database.SaveCharacterDisc(char_id, r, spell_id_);
|
||||
change = true;
|
||||
initiator->Message(0, "You have learned a new discipline!");
|
||||
++count;
|
||||
}
|
||||
break;
|
||||
}
|
||||
else {
|
||||
initiator->GetPP().disciplines.values[r] = spell_id_;
|
||||
database.SaveCharacterDisc(char_id, r, spell_id_);
|
||||
change = true;;
|
||||
initiator->Message(0, "You have learned a new discipline!");
|
||||
++count; // success counter
|
||||
break; // continue the 1st loop
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
return count; //how many disciplines were learned successfully
|
||||
|
||||
if (change)
|
||||
initiator->SendDisciplineUpdate();
|
||||
|
||||
return count; // how many disciplines were learned successfully
|
||||
}
|
||||
|
||||
void QuestManager::unscribespells() {
|
||||
QuestManagerCurrentQuestVars();
|
||||
initiator->UnscribeSpellAll();
|
||||
}
|
||||
}
|
||||
|
||||
void QuestManager::untraindiscs() {
|
||||
QuestManagerCurrentQuestVars();
|
||||
@@ -2126,7 +2181,7 @@ bool QuestManager::createBot(const char *name, const char *lastname, uint8 level
|
||||
|
||||
std::string test_name = name;
|
||||
bool available_flag = false;
|
||||
if(!botdb.QueryNameAvailablity(test_name, available_flag)) {
|
||||
if(!database.botdb.QueryNameAvailablity(test_name, available_flag)) {
|
||||
initiator->Message(0, "%s for '%s'", BotDatabase::fail::QueryNameAvailablity(), (char*)name);
|
||||
return false;
|
||||
}
|
||||
@@ -2135,8 +2190,7 @@ bool QuestManager::createBot(const char *name, const char *lastname, uint8 level
|
||||
return false;
|
||||
}
|
||||
|
||||
NPCType DefaultNPCTypeStruct = Bot::CreateDefaultNPCTypeStructForBot(name, lastname, level, race, botclass, gender);
|
||||
Bot* NewBot = new Bot(DefaultNPCTypeStruct, initiator);
|
||||
Bot* NewBot = new Bot(Bot::CreateDefaultNPCTypeStructForBot(name, lastname, level, race, botclass, gender), initiator);
|
||||
|
||||
if(NewBot)
|
||||
{
|
||||
@@ -2845,7 +2899,7 @@ uint8 QuestManager::FactionValue()
|
||||
FACTION_VALUE oldfac;
|
||||
uint8 newfac = 0;
|
||||
if(initiator && owner->IsNPC()) {
|
||||
oldfac = initiator->GetFactionLevel(initiator->GetID(), owner->GetID(), initiator->GetRace(), initiator->GetClass(), initiator->GetDeity(), owner->GetPrimaryFaction(), owner);
|
||||
oldfac = initiator->GetFactionLevel(initiator->GetID(), owner->GetID(), initiator->GetFactionRace(), initiator->GetClass(), initiator->GetDeity(), owner->GetPrimaryFaction(), owner);
|
||||
|
||||
// now, reorder the faction to have it make sense (higher values are better)
|
||||
switch (oldfac) {
|
||||
|
||||
@@ -1278,6 +1278,7 @@ void Client::ThrowingAttack(Mob* other, bool CanDoubleAttack) { //old was 51
|
||||
}
|
||||
else if(dist < (RuleI(Combat, MinRangedAttackDist)*RuleI(Combat, MinRangedAttackDist))){
|
||||
Message_StringID(15,RANGED_TOO_CLOSE);//Client enforces range and sends the message, this is a backup just incase.
|
||||
return;
|
||||
}
|
||||
|
||||
if(!IsAttackAllowed(other) ||
|
||||
|
||||
+67
-19
@@ -100,6 +100,7 @@ Copyright (C) 2001-2002 EQEMu Development Team (http://eqemu.org)
|
||||
#include "bot.h"
|
||||
#endif
|
||||
|
||||
#include "mob_movement_manager.h"
|
||||
|
||||
|
||||
extern Zone* zone;
|
||||
@@ -454,7 +455,7 @@ bool Mob::DoCastSpell(uint16 spell_id, uint16 target_id, CastingSlot slot,
|
||||
{
|
||||
mana_cost = 0;
|
||||
} else {
|
||||
Log(Logs::Detail, Logs::Spells, "Spell Error not enough mana spell=%d mymana=%d cost=%d\n", GetName(), spell_id, my_curmana, mana_cost);
|
||||
Log(Logs::Detail, Logs::Spells, "Spell Error not enough mana spell=%d mymana=%d cost=%d\n", spell_id, my_curmana, mana_cost);
|
||||
if(IsClient()) {
|
||||
//clients produce messages... npcs should not for this case
|
||||
Message_StringID(13, INSUFFICIENT_MANA);
|
||||
@@ -4031,6 +4032,23 @@ bool Mob::FindBuff(uint16 spellid)
|
||||
return false;
|
||||
}
|
||||
|
||||
uint16 Mob::FindBuffBySlot(int slot) {
|
||||
if (buffs[slot].spellid != SPELL_UNKNOWN)
|
||||
return buffs[slot].spellid;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32 Mob::BuffCount() {
|
||||
uint32 active_buff_count = 0;
|
||||
int buff_count = GetMaxTotalSlots();
|
||||
for (int i = 0; i < buff_count; i++)
|
||||
if (buffs[i].spellid != SPELL_UNKNOWN)
|
||||
active_buff_count++;
|
||||
|
||||
return active_buff_count;
|
||||
}
|
||||
|
||||
// removes all buffs
|
||||
void Mob::BuffFadeAll()
|
||||
{
|
||||
@@ -4205,7 +4223,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster)
|
||||
{
|
||||
if(GetSpecialAbility(UNMEZABLE)) {
|
||||
Log(Logs::Detail, Logs::Spells, "We are immune to Mez spells.");
|
||||
caster->Message_StringID(MT_Shout, CANNOT_MEZ);
|
||||
caster->Message_StringID(MT_SpellFailure, CANNOT_MEZ);
|
||||
int32 aggro = caster->CheckAggroAmount(spell_id, this);
|
||||
if(aggro > 0) {
|
||||
AddToHateList(caster, aggro);
|
||||
@@ -4223,7 +4241,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster)
|
||||
(!caster->IsNPC() || (caster->IsNPC() && !RuleB(Spells, NPCIgnoreBaseImmunity))))
|
||||
{
|
||||
Log(Logs::Detail, Logs::Spells, "Our level (%d) is higher than the limit of this Mez spell (%d)", GetLevel(), spells[spell_id].max[effect_index]);
|
||||
caster->Message_StringID(MT_Shout, CANNOT_MEZ_WITH_SPELL);
|
||||
caster->Message_StringID(MT_SpellFailure, CANNOT_MEZ_WITH_SPELL);
|
||||
AddToHateList(caster, 1,0,true,false,false,spell_id);
|
||||
return true;
|
||||
}
|
||||
@@ -4233,7 +4251,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster)
|
||||
if(GetSpecialAbility(UNSLOWABLE) && IsEffectInSpell(spell_id, SE_AttackSpeed))
|
||||
{
|
||||
Log(Logs::Detail, Logs::Spells, "We are immune to Slow spells.");
|
||||
caster->Message_StringID(MT_Shout, IMMUNE_ATKSPEED);
|
||||
caster->Message_StringID(CC_Red, IMMUNE_ATKSPEED);
|
||||
int32 aggro = caster->CheckAggroAmount(spell_id, this);
|
||||
if(aggro > 0) {
|
||||
AddToHateList(caster, aggro);
|
||||
@@ -4249,7 +4267,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster)
|
||||
effect_index = GetSpellEffectIndex(spell_id, SE_Fear);
|
||||
if(GetSpecialAbility(UNFEARABLE)) {
|
||||
Log(Logs::Detail, Logs::Spells, "We are immune to Fear spells.");
|
||||
caster->Message_StringID(MT_Shout, IMMUNE_FEAR);
|
||||
caster->Message_StringID(CC_Red, IMMUNE_FEAR); // need to verify message type, not in MQ2Cast for easy look up
|
||||
int32 aggro = caster->CheckAggroAmount(spell_id, this);
|
||||
if(aggro > 0) {
|
||||
AddToHateList(caster, aggro);
|
||||
@@ -4260,7 +4278,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster)
|
||||
} else if(IsClient() && caster->IsClient() && (caster->CastToClient()->GetGM() == false))
|
||||
{
|
||||
Log(Logs::Detail, Logs::Spells, "Clients cannot fear eachother!");
|
||||
caster->Message_StringID(MT_Shout, IMMUNE_FEAR);
|
||||
caster->Message_StringID(CC_Red, IMMUNE_FEAR); // need to verify message type, not in MQ2Cast for easy look up
|
||||
return true;
|
||||
}
|
||||
else if(GetLevel() > spells[spell_id].max[effect_index] && spells[spell_id].max[effect_index] != 0)
|
||||
@@ -4279,7 +4297,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster)
|
||||
{
|
||||
Message(13, "Your are immune to fear.");
|
||||
Log(Logs::Detail, Logs::Spells, "Clients has WarCry effect, immune to fear!");
|
||||
caster->Message_StringID(MT_Shout, IMMUNE_FEAR);
|
||||
caster->Message_StringID(CC_Red, IMMUNE_FEAR); // need to verify message type, not in MQ2Cast for easy look up
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -4289,7 +4307,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster)
|
||||
if(GetSpecialAbility(UNCHARMABLE))
|
||||
{
|
||||
Log(Logs::Detail, Logs::Spells, "We are immune to Charm spells.");
|
||||
caster->Message_StringID(MT_Shout, CANNOT_CHARM);
|
||||
caster->Message_StringID(CC_Red, CANNOT_CHARM); // need to verify message type, not in MQ2Cast for easy look up
|
||||
int32 aggro = caster->CheckAggroAmount(spell_id, this);
|
||||
if(aggro > 0) {
|
||||
AddToHateList(caster, aggro);
|
||||
@@ -4302,7 +4320,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster)
|
||||
if(this == caster)
|
||||
{
|
||||
Log(Logs::Detail, Logs::Spells, "You are immune to your own charms.");
|
||||
caster->Message(MT_Shout, "You cannot charm yourself.");
|
||||
caster->Message(CC_Red, "You cannot charm yourself."); // need to look up message?
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -4315,8 +4333,8 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster)
|
||||
if(GetLevel() > spells[spell_id].max[effect_index] && spells[spell_id].max[effect_index] != 0)
|
||||
{
|
||||
Log(Logs::Detail, Logs::Spells, "Our level (%d) is higher than the limit of this Charm spell (%d)", GetLevel(), spells[spell_id].max[effect_index]);
|
||||
caster->Message_StringID(MT_Shout, CANNOT_CHARM_YET);
|
||||
AddToHateList(caster, 1,0,true,false,false,spell_id);
|
||||
caster->Message_StringID(CC_Red, CANNOT_CHARM_YET); // need to verify message type, not in MQ2Cast for easy look up<Paste>
|
||||
AddToHateList(caster, 1,0,true,false,false,spell_id);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -4330,7 +4348,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster)
|
||||
{
|
||||
if(GetSpecialAbility(UNSNAREABLE)) {
|
||||
Log(Logs::Detail, Logs::Spells, "We are immune to Snare spells.");
|
||||
caster->Message_StringID(MT_Shout, IMMUNE_MOVEMENT);
|
||||
caster->Message_StringID(CC_Red, IMMUNE_MOVEMENT);
|
||||
int32 aggro = caster->CheckAggroAmount(spell_id, this);
|
||||
if(aggro > 0) {
|
||||
AddToHateList(caster, aggro);
|
||||
@@ -4346,7 +4364,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster)
|
||||
if(this == caster)
|
||||
{
|
||||
Log(Logs::Detail, Logs::Spells, "You cannot lifetap yourself.");
|
||||
caster->Message_StringID(MT_Shout, CANT_DRAIN_SELF);
|
||||
caster->Message_StringID(MT_SpellFailure, CANT_DRAIN_SELF);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -4356,7 +4374,7 @@ bool Mob::IsImmuneToSpell(uint16 spell_id, Mob *caster)
|
||||
if(this == caster)
|
||||
{
|
||||
Log(Logs::Detail, Logs::Spells, "You cannot sacrifice yourself.");
|
||||
caster->Message_StringID(MT_Shout, CANNOT_SAC_SELF);
|
||||
caster->Message_StringID(MT_SpellFailure, CANNOT_SAC_SELF);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -4818,7 +4836,22 @@ void Mob::Spin() {
|
||||
safe_delete(outapp);
|
||||
}
|
||||
else {
|
||||
GMMove(GetX(), GetY(), GetZ(), GetHeading()+5);
|
||||
float x,y,z,h;
|
||||
|
||||
x=GetX();
|
||||
y=GetY();
|
||||
z=GetZ();
|
||||
h=GetHeading()+5;
|
||||
|
||||
if (IsCorpse() || (IsClient() && !IsAIControlled())) {
|
||||
m_Position.x = x;
|
||||
m_Position.y = y;
|
||||
m_Position.z = z;
|
||||
mMovementManager->SendCommandToClients(this, 0.0, 0.0, 0.0, 0.0, 0, ClientRangeAny);
|
||||
}
|
||||
else {
|
||||
Teleport(glm::vec4(x, y, z, h));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5023,6 +5056,23 @@ void Client::UnmemSpellAll(bool update_client)
|
||||
UnmemSpell(i, update_client);
|
||||
}
|
||||
|
||||
uint16 Client::FindMemmedSpellBySlot(int slot) {
|
||||
if (m_pp.mem_spells[slot] != 0xFFFFFFFF)
|
||||
return m_pp.mem_spells[slot];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Client::MemmedCount() {
|
||||
int memmed_count = 0;
|
||||
for (int i = 0; i < EQEmu::spells::SPELL_GEM_COUNT; i++)
|
||||
if (m_pp.mem_spells[i] != 0xFFFFFFFF)
|
||||
memmed_count++;
|
||||
|
||||
return memmed_count;
|
||||
}
|
||||
|
||||
|
||||
void Client::ScribeSpell(uint16 spell_id, int slot, bool update_client)
|
||||
{
|
||||
if(slot >= EQEmu::spells::SPELLBOOK_SIZE || slot < 0)
|
||||
@@ -5053,7 +5103,7 @@ void Client::UnscribeSpell(int slot, bool update_client)
|
||||
m_pp.spell_book[slot] = 0xFFFFFFFF;
|
||||
|
||||
database.DeleteCharacterSpell(this->CharacterID(), m_pp.spell_book[slot], slot);
|
||||
if(update_client)
|
||||
if(update_client && slot < EQEmu::spells::DynamicLookup(ClientVersion(), GetGM())->SpellbookSize)
|
||||
{
|
||||
auto outapp = new EQApplicationPacket(OP_DeleteSpell, sizeof(DeleteSpell_Struct));
|
||||
DeleteSpell_Struct* del = (DeleteSpell_Struct*)outapp->pBuffer;
|
||||
@@ -5066,9 +5116,7 @@ void Client::UnscribeSpell(int slot, bool update_client)
|
||||
|
||||
void Client::UnscribeSpellAll(bool update_client)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; i < EQEmu::spells::SPELLBOOK_SIZE; i++)
|
||||
for(int i = 0; i < EQEmu::spells::SPELLBOOK_SIZE; i++)
|
||||
{
|
||||
if(m_pp.spell_book[i] != 0xFFFFFFFF)
|
||||
UnscribeSpell(i, update_client);
|
||||
|
||||
@@ -30,7 +30,8 @@ bool WaterMapV2::InLava(const glm::vec3& location) const {
|
||||
}
|
||||
|
||||
bool WaterMapV2::InLiquid(const glm::vec3& location) const {
|
||||
return InWater(location) || InLava(location) || InVWater(location);
|
||||
auto rt = ReturnRegionType(location);
|
||||
return rt == RegionTypeWater || rt == RegionTypeVWater || rt == RegionTypeLava;
|
||||
}
|
||||
|
||||
bool WaterMapV2::InPvP(const glm::vec3& location) const {
|
||||
|
||||
+59
-26
@@ -24,6 +24,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#include "../common/rulesys.h"
|
||||
#include "../common/string_util.h"
|
||||
#include "../common/misc_functions.h"
|
||||
#include "../common/eqemu_logsys.h"
|
||||
#include "../common/eqemu_logsys_fmt.h"
|
||||
|
||||
#include "map.h"
|
||||
#include "npc.h"
|
||||
@@ -108,7 +110,7 @@ void NPC::ResumeWandering()
|
||||
{ // we were paused by a quest
|
||||
AI_walking_timer->Disable();
|
||||
SetGrid(0 - GetGrid());
|
||||
if (cur_wp == -1)
|
||||
if (cur_wp == EQEmu::WaypointStatus::QuestControlGrid)
|
||||
{ // got here by a MoveTo()
|
||||
cur_wp = save_wp;
|
||||
UpdateWaypoint(cur_wp); // have him head to last destination from here
|
||||
@@ -164,28 +166,32 @@ void NPC::PauseWandering(int pausetime)
|
||||
return;
|
||||
}
|
||||
|
||||
void NPC::MoveTo(const glm::vec4& position, bool saveguardspot)
|
||||
{ // makes mob walk to specified location
|
||||
if (IsNPC() && GetGrid() != 0)
|
||||
{ // he is on a grid
|
||||
if (GetGrid() < 0)
|
||||
{ // currently stopped by a quest command
|
||||
SetGrid(0 - GetGrid()); // get him moving again
|
||||
Log(Logs::Detail, Logs::AI, "MoveTo during quest wandering. Canceling quest wandering and going back to grid %d when MoveTo is done.", GetGrid());
|
||||
void NPC::MoveTo(const glm::vec4 &position, bool saveguardspot)
|
||||
{ // makes mob walk to specified location
|
||||
if (IsNPC() && GetGrid() != 0) { // he is on a grid
|
||||
if (GetGrid() < 0) { // currently stopped by a quest command
|
||||
SetGrid(0 - GetGrid()); // get him moving again
|
||||
Log(Logs::Detail,
|
||||
Logs::AI,
|
||||
"MoveTo during quest wandering. Canceling quest wandering and going back to grid %d when MoveTo is done.",
|
||||
GetGrid());
|
||||
}
|
||||
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
|
||||
cur_wp = -1; // flag this move as quest controlled
|
||||
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
|
||||
cur_wp = EQEmu::WaypointStatus::QuestControlGrid;
|
||||
}
|
||||
Log(Logs::Detail, Logs::AI, "MoveTo %s, pausing regular grid wandering. Grid %d, save_wp %d", to_string(static_cast<glm::vec3>(position)).c_str(), -GetGrid(), save_wp);
|
||||
Log(Logs::Detail,
|
||||
Logs::AI,
|
||||
"MoveTo %s, pausing regular grid wandering. Grid %d, save_wp %d",
|
||||
to_string(static_cast<glm::vec3>(position)).c_str(),
|
||||
-GetGrid(),
|
||||
save_wp);
|
||||
}
|
||||
else
|
||||
{ // not on a grid
|
||||
roamer = true;
|
||||
else { // not on a grid
|
||||
roamer = true;
|
||||
save_wp = 0;
|
||||
cur_wp = -2; // flag as quest controlled w/no grid
|
||||
cur_wp = EQEmu::WaypointStatus::QuestControlNoGrid;
|
||||
Log(Logs::Detail, Logs::AI, "MoveTo %s without a grid.", to_string(static_cast<glm::vec3>(position)).c_str());
|
||||
}
|
||||
|
||||
@@ -194,23 +200,27 @@ void NPC::MoveTo(const glm::vec4& position, bool saveguardspot)
|
||||
m_CurrentWayPoint = position;
|
||||
m_CurrentWayPoint.z = GetFixedZ(dest);
|
||||
|
||||
if (saveguardspot)
|
||||
{
|
||||
if (saveguardspot) {
|
||||
m_GuardPoint = m_CurrentWayPoint;
|
||||
|
||||
if (m_GuardPoint.w == 0)
|
||||
m_GuardPoint.w = 0.0001; //hack to make IsGuarding simpler
|
||||
if (m_GuardPoint.w == 0) {
|
||||
m_GuardPoint.w = 0.0001;
|
||||
} //hack to make IsGuarding simpler
|
||||
|
||||
if (m_GuardPoint.w == -1)
|
||||
m_GuardPoint.w = this->CalculateHeadingToTarget(position.x, position.y);
|
||||
|
||||
Log(Logs::Detail, Logs::AI, "Setting guard position to %s", to_string(static_cast<glm::vec3>(m_GuardPoint)).c_str());
|
||||
Log(Logs::Detail,
|
||||
Logs::AI,
|
||||
"Setting guard position to %s",
|
||||
to_string(static_cast<glm::vec3>(m_GuardPoint)).c_str());
|
||||
}
|
||||
|
||||
cur_wp_pause = 0;
|
||||
cur_wp_pause = 0;
|
||||
time_until_can_move = 0;
|
||||
if (AI_walking_timer->Enabled())
|
||||
if (AI_walking_timer->Enabled()) {
|
||||
AI_walking_timer->Start(100);
|
||||
}
|
||||
}
|
||||
|
||||
void NPC::UpdateWaypoint(int wp_index)
|
||||
@@ -1063,3 +1073,26 @@ void NPC::RestoreGuardSpotCharm()
|
||||
{
|
||||
m_GuardPoint = m_GuardPointSaved;
|
||||
}
|
||||
|
||||
/******************
|
||||
* Bot-specific overloads to make them play nice with the new movement system
|
||||
*/
|
||||
#ifdef BOTS
|
||||
#include "bot.h"
|
||||
|
||||
void Bot::WalkTo(float x, float y, float z)
|
||||
{
|
||||
if (IsSitting())
|
||||
Stand();
|
||||
|
||||
Mob::WalkTo(x, y, z);
|
||||
}
|
||||
|
||||
void Bot::RunTo(float x, float y, float z)
|
||||
{
|
||||
if (IsSitting())
|
||||
Stand();
|
||||
|
||||
Mob::RunTo(x, y, z);
|
||||
}
|
||||
#endif
|
||||
|
||||
+10
-4
@@ -36,6 +36,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#include "../common/misc_functions.h"
|
||||
#include "../common/rulesys.h"
|
||||
#include "../common/servertalk.h"
|
||||
#include "../common/profanity_manager.h"
|
||||
|
||||
#include "client.h"
|
||||
#include "corpse.h"
|
||||
@@ -793,6 +794,11 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ServerOP_RefreshCensorship: {
|
||||
if (!EQEmu::ProfanityManager::LoadProfanityList(&database))
|
||||
Log(Logs::General, Logs::Error, "Received request to refresh the profanity list..but, the action failed");
|
||||
break;
|
||||
}
|
||||
case ServerOP_ChangeWID: {
|
||||
if (pack->size != sizeof(ServerChangeWID_Struct)) {
|
||||
std::cout << "Wrong size on ServerChangeWID_Struct. Got: " << pack->size << ", Expected: " << sizeof(ServerChangeWID_Struct) << std::endl;
|
||||
@@ -1767,10 +1773,10 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p)
|
||||
}
|
||||
case ServerOP_ReloadRules: {
|
||||
worldserver.SendEmoteMessage(
|
||||
0, 0, 0, 15,
|
||||
"Rules reloaded for Zone: '%s' Instance ID: %u",
|
||||
zone->GetLongName(),
|
||||
zone->GetInstanceID()
|
||||
0, 0, 100, 15,
|
||||
"Rules reloaded for Zone: '%s' Instance ID: %u",
|
||||
zone->GetLongName(),
|
||||
zone->GetInstanceID()
|
||||
);
|
||||
RuleManager::Instance()->LoadRules(&database, RuleManager::Instance()->GetActiveRuleset(), true);
|
||||
break;
|
||||
|
||||
+2
-29
@@ -1072,14 +1072,14 @@ bool Zone::LoadZoneCFG(const char* filename, uint16 instance_id)
|
||||
map_name = nullptr;
|
||||
|
||||
if(!database.GetZoneCFG(database.GetZoneID(filename), instance_id, &newzone_data, can_bind,
|
||||
can_combat, can_levitate, can_castoutdoor, is_city, is_hotzone, allow_mercs, zone_type, default_ruleset, &map_name))
|
||||
can_combat, can_levitate, can_castoutdoor, is_city, is_hotzone, allow_mercs, max_movement_update_range, zone_type, default_ruleset, &map_name))
|
||||
{
|
||||
// If loading a non-zero instance failed, try loading the default
|
||||
if (instance_id != 0)
|
||||
{
|
||||
safe_delete_array(map_name);
|
||||
if(!database.GetZoneCFG(database.GetZoneID(filename), 0, &newzone_data, can_bind, can_combat, can_levitate,
|
||||
can_castoutdoor, is_city, is_hotzone, allow_mercs, zone_type, default_ruleset, &map_name))
|
||||
can_castoutdoor, is_city, is_hotzone, allow_mercs, max_movement_update_range, zone_type, default_ruleset, &map_name))
|
||||
{
|
||||
Log(Logs::General, Logs::Error, "Error loading the Zone Config.");
|
||||
return false;
|
||||
@@ -1837,33 +1837,6 @@ void Zone::ShowSpawnStatusByID(Mob* client, uint32 spawnid)
|
||||
client->Message(0, "No matching spawn id was found in this zone.");
|
||||
}
|
||||
|
||||
|
||||
bool Zone::RemoveSpawnEntry(uint32 spawnid)
|
||||
{
|
||||
LinkedListIterator<Spawn2*> iterator(spawn2_list);
|
||||
|
||||
|
||||
iterator.Reset();
|
||||
while(iterator.MoreElements())
|
||||
{
|
||||
if(iterator.GetData()->GetID() == spawnid)
|
||||
{
|
||||
iterator.RemoveCurrent();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
iterator.Advance();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Zone::RemoveSpawnGroup(uint32 in_id) {
|
||||
if(spawn_group_list.RemoveSpawnGroup(in_id))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ZoneDatabase::GetDecayTimes(npcDecayTimes_Struct *npcCorpseDecayTimes)
|
||||
{
|
||||
const std::string query =
|
||||
|
||||
+268
-264
@@ -31,32 +31,31 @@
|
||||
#include "pathfinder_interface.h"
|
||||
#include "global_loot_manager.h"
|
||||
|
||||
struct ZonePoint
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
float heading;
|
||||
struct ZonePoint {
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
float heading;
|
||||
uint16 number;
|
||||
float target_x;
|
||||
float target_y;
|
||||
float target_z;
|
||||
float target_heading;
|
||||
float target_x;
|
||||
float target_y;
|
||||
float target_z;
|
||||
float target_heading;
|
||||
uint16 target_zone_id;
|
||||
int32 target_zone_instance;
|
||||
int32 target_zone_instance;
|
||||
uint32 client_version_mask;
|
||||
};
|
||||
|
||||
struct ZoneClientAuth_Struct {
|
||||
uint32 ip; // client's IP address
|
||||
uint32 wid; // client's WorldID#
|
||||
uint32 accid;
|
||||
int16 admin;
|
||||
uint32 charid;
|
||||
bool tellsoff;
|
||||
char charname[64];
|
||||
char lskey[30];
|
||||
bool stale;
|
||||
uint32 ip; // client's IP address
|
||||
uint32 wid; // client's WorldID#
|
||||
uint32 accid;
|
||||
int16 admin;
|
||||
uint32 charid;
|
||||
bool tellsoff;
|
||||
char charname[64];
|
||||
char lskey[30];
|
||||
bool stale;
|
||||
};
|
||||
|
||||
struct ZoneEXPModInfo {
|
||||
@@ -65,11 +64,11 @@ struct ZoneEXPModInfo {
|
||||
};
|
||||
|
||||
struct item_tick_struct {
|
||||
uint32 itemid;
|
||||
uint32 chance;
|
||||
uint32 level;
|
||||
int16 bagslot;
|
||||
std::string qglobal;
|
||||
uint32 itemid;
|
||||
uint32 chance;
|
||||
uint32 level;
|
||||
int16 bagslot;
|
||||
std::string qglobal;
|
||||
};
|
||||
|
||||
class Client;
|
||||
@@ -81,290 +80,295 @@ struct NPCType;
|
||||
struct ServerZoneIncomingClient_Struct;
|
||||
class MobMovementManager;
|
||||
|
||||
class Zone
|
||||
{
|
||||
class Zone {
|
||||
public:
|
||||
static bool Bootup(uint32 iZoneID, uint32 iInstanceID, bool iStaticZone = false);
|
||||
static void Shutdown(bool quite = false);
|
||||
|
||||
Zone(uint32 in_zoneid, uint32 in_instanceid, const char* in_short_name);
|
||||
Zone(uint32 in_zoneid, uint32 in_instanceid, const char *in_short_name);
|
||||
~Zone();
|
||||
|
||||
/* When zone has its own version of time */
|
||||
bool is_zone_time_localized;
|
||||
|
||||
bool Init(bool iStaticZone);
|
||||
bool LoadZoneCFG(const char* filename, uint16 instance_id);
|
||||
bool SaveZoneCFG();
|
||||
bool IsLoaded();
|
||||
bool IsPVPZone() { return pvpzone; }
|
||||
inline const char* GetLongName() { return long_name; }
|
||||
inline const char* GetFileName() { return file_name; }
|
||||
inline const char* GetShortName() { return short_name; }
|
||||
inline const uint32 GetZoneID() const { return zoneid; }
|
||||
inline const uint32 GetInstanceID() const { return instanceid; }
|
||||
inline const uint16 GetInstanceVersion() const { return instanceversion; }
|
||||
inline const bool IsInstancePersistent() const { return pers_instance; }
|
||||
inline const uint8 GetZoneType() const { return zone_type; }
|
||||
|
||||
inline Timer* GetInstanceTimer() { return Instance_Timer; }
|
||||
Timer spawn2_timer;
|
||||
|
||||
inline glm::vec3 GetSafePoint() { return m_SafePoint; }
|
||||
inline const uint32& graveyard_zoneid() { return pgraveyard_zoneid; }
|
||||
inline glm::vec4 GetGraveyardPoint() { return m_Graveyard; }
|
||||
inline const uint32& graveyard_id() { return pgraveyard_id; }
|
||||
|
||||
inline const uint32& GetMaxClients() { return pMaxClients; }
|
||||
|
||||
//new AA
|
||||
void LoadAlternateAdvancement();
|
||||
AA::Ability *GetAlternateAdvancementAbility(int id);
|
||||
AA::Ability *GetAlternateAdvancementAbilityByRank(int rank_id);
|
||||
AA::Rank *GetAlternateAdvancementRank(int rank_id);
|
||||
std::pair<AA::Ability*, AA::Rank*> GetAlternateAdvancementAbilityAndRank(int id, int points_spent);
|
||||
|
||||
void LoadZoneDoors(const char* zone, int16 version);
|
||||
bool LoadZoneObjects();
|
||||
bool LoadGroundSpawns();
|
||||
void ReloadStaticData();
|
||||
|
||||
uint32 CountSpawn2();
|
||||
ZonePoint* GetClosestZonePoint(const glm::vec3& location, const char* to_name, Client *client, float max_distance = 40000.0f);
|
||||
ZonePoint* GetClosestZonePoint(const glm::vec3& location, uint32 to, Client *client, float max_distance = 40000.0f);
|
||||
ZonePoint* GetClosestZonePointWithoutZone(float x, float y, float z, Client *client, float max_distance = 40000.0f);
|
||||
SpawnGroupList spawn_group_list;
|
||||
|
||||
bool RemoveSpawnEntry(uint32 spawnid);
|
||||
bool RemoveSpawnGroup(uint32 in_id);
|
||||
|
||||
bool Process();
|
||||
void Despawn(uint32 spawngroupID);
|
||||
|
||||
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);
|
||||
void ShowDisabledSpawnStatus(Mob* client);
|
||||
void ShowSpawnStatusByID(Mob* client, uint32 spawnid);
|
||||
void StartShutdownTimer(uint32 set_time = (RuleI(Zone, AutoShutdownDelay)));
|
||||
void ChangeWeather();
|
||||
bool HasWeather();
|
||||
void AddAuth(ServerZoneIncomingClient_Struct* szic);
|
||||
void RemoveAuth(const char* iCharName);
|
||||
void ResetAuth();
|
||||
bool GetAuth(uint32 iIP, const char* iCharName, uint32* oWID = 0, uint32* oAccID = 0, uint32* oCharID = 0, int16* oStatus = 0, char* oLSKey = 0, bool* oTellsOff = 0);
|
||||
uint32 CountAuth();
|
||||
|
||||
void AddAggroMob() { aggroedmobs++; }
|
||||
void DelAggroMob() { aggroedmobs--; }
|
||||
bool AggroLimitReached() { return (aggroedmobs>10)?true:false; } // change this value, to allow more NPCs to autoaggro
|
||||
int32 MobsAggroCount() { return aggroedmobs; }
|
||||
inline bool InstantGrids() { return(!initgrids_timer.Enabled()); }
|
||||
void SetStaticZone(bool sz) { staticzone = sz; }
|
||||
inline bool IsStaticZone() { return staticzone; }
|
||||
inline void SetZoneHasCurrentTime(bool time) { zone_has_current_time = time; }
|
||||
|
||||
void SpawnConditionChanged(const SpawnCondition &c, int16 old_value);
|
||||
|
||||
void GetMerchantDataForZoneLoad();
|
||||
void LoadNewMerchantData(uint32 merchantid);
|
||||
void LoadTempMerchantData();
|
||||
uint32 GetTempMerchantQuantity(uint32 NPCID, uint32 Slot);
|
||||
int SaveTempItem(uint32 merchantid, uint32 npcid, uint32 item, int32 charges, bool sold=false);
|
||||
void LoadMercTemplates();
|
||||
void LoadMercSpells();
|
||||
void LoadLevelEXPMods();
|
||||
MercTemplate* GetMercTemplate( uint32 template_id );
|
||||
|
||||
void SetInstanceTimer(uint32 new_duration);
|
||||
void LoadLDoNTraps();
|
||||
void LoadLDoNTrapEntries();
|
||||
void LoadAdventureFlavor();
|
||||
|
||||
std::map<uint32,NPCType *> npctable;
|
||||
std::map<uint32,NPCType *> merctable;
|
||||
std::map<uint32,std::list<MerchantList> > merchanttable;
|
||||
std::map<uint32,std::list<TempMerchantList> > tmpmerchanttable;
|
||||
std::map<uint32,std::string> adventure_entry_list_flavor;
|
||||
std::map<uint32,LDoNTrapTemplate*> ldon_trap_list;
|
||||
std::map<uint32,std::list<LDoNTrapTemplate*> > ldon_trap_entry_list;
|
||||
std::map<uint32,std::list<MercStanceInfo> > merc_stance_list;
|
||||
std::map<uint32, MercTemplate> merc_templates;
|
||||
std::map<uint32,std::list<MercSpellEntry> > merc_spells_list;
|
||||
std::map<uint32, ZoneEXPModInfo> level_exp_mod;
|
||||
std::list<InternalVeteranReward> VeteranRewards;
|
||||
std::list<AltCurrencyDefinition_Struct> AlternateCurrencies;
|
||||
char *adv_data;
|
||||
bool is_zone_time_localized;
|
||||
bool AggroLimitReached() { return (aggroedmobs > 10) ? true : false; }
|
||||
bool AllowMercs() const { return (allow_mercs); }
|
||||
bool CanBind() const { return (can_bind); }
|
||||
bool CanCastOutdoor() const { return (can_castoutdoor); } //qadar
|
||||
bool CanDoCombat() const { return (can_combat); }
|
||||
bool CanLevitate() const { return (can_levitate); } // Magoth78
|
||||
bool Depop(bool StartSpawnTimer = false);
|
||||
bool did_adventure_actions;
|
||||
bool GetAuth(
|
||||
uint32 iIP,
|
||||
const char *iCharName,
|
||||
uint32 *oWID = 0,
|
||||
uint32 *oAccID = 0,
|
||||
uint32 *oCharID = 0,
|
||||
int16 *oStatus = 0,
|
||||
char *oLSKey = 0,
|
||||
bool *oTellsOff = 0
|
||||
);
|
||||
bool HasGraveyard();
|
||||
bool HasWeather();
|
||||
bool Init(bool iStaticZone);
|
||||
bool IsCity() const { return (is_city); }
|
||||
bool IsHotzone() const { return (is_hotzone); }
|
||||
bool IsLoaded();
|
||||
bool IsPVPZone() { return pvpzone; }
|
||||
bool IsSpellBlocked(uint32 spell_id, const glm::vec3 &location);
|
||||
bool IsUCSServerAvailable() { return m_ucss_available; }
|
||||
bool LoadGroundSpawns();
|
||||
bool LoadZoneCFG(const char *filename, uint16 instance_id);
|
||||
bool LoadZoneObjects();
|
||||
bool Process();
|
||||
bool SaveZoneCFG();
|
||||
|
||||
//new AA
|
||||
std::unordered_map<int, std::unique_ptr<AA::Ability>> aa_abilities;
|
||||
std::unordered_map<int, std::unique_ptr<AA::Rank>> aa_ranks;
|
||||
char *adv_data;
|
||||
|
||||
void DoAdventureCountIncrease();
|
||||
void DoAdventureAssassinationCountIncrease();
|
||||
void DoAdventureActions();
|
||||
void LoadVeteranRewards();
|
||||
void LoadAlternateCurrencies();
|
||||
void LoadNPCEmotes(LinkedList<NPC_Emote_Struct*>* NPCEmoteList);
|
||||
void ReloadWorld(uint32 Option);
|
||||
void ReloadMerchants();
|
||||
const char *GetSpellBlockedMessage(uint32 spell_id, const glm::vec3 &location);
|
||||
|
||||
Map *zonemap;
|
||||
WaterMap *watermap;
|
||||
IPathfinder *pathing;
|
||||
NewZone_Struct newzone_data;
|
||||
EQEmu::Random random;
|
||||
EQTime zone_time;
|
||||
|
||||
SpawnConditionManager spawn_conditions;
|
||||
ZonePoint *GetClosestZonePoint(const glm::vec3 &location, const char *to_name, Client *client, float max_distance = 40000.0f);
|
||||
|
||||
EQTime zone_time;
|
||||
void GetTimeSync();
|
||||
void SetDate(uint16 year, uint8 month, uint8 day, uint8 hour, uint8 minute);
|
||||
void SetTime(uint8 hour, uint8 minute, bool update_world = true);
|
||||
|
||||
void weatherSend(Client* client = nullptr);
|
||||
bool CanBind() const { return(can_bind); }
|
||||
bool IsCity() const { return(is_city); }
|
||||
bool CanDoCombat() const { return(can_combat); }
|
||||
bool CanLevitate() const {return(can_levitate); } // Magoth78
|
||||
bool CanCastOutdoor() const {return(can_castoutdoor);} //qadar
|
||||
bool AllowMercs() const {return(allow_mercs);}
|
||||
bool IsHotzone() const { return(is_hotzone); }
|
||||
inline bool BuffTimersSuspended() const { return newzone_data.SuspendBuffs != 0; };
|
||||
|
||||
time_t weather_timer;
|
||||
uint8 weather_intensity;
|
||||
uint8 zone_weather;
|
||||
|
||||
uint8 loglevelvar;
|
||||
uint8 merchantvar;
|
||||
uint8 tradevar;
|
||||
uint8 lootvar;
|
||||
|
||||
bool HasGraveyard();
|
||||
void SetGraveyard(uint32 zoneid, const glm::vec4& graveyardPosition);
|
||||
|
||||
void LoadBlockedSpells(uint32 zoneid);
|
||||
void ClearBlockedSpells();
|
||||
bool IsSpellBlocked(uint32 spell_id, const glm::vec3& location);
|
||||
const char *GetSpellBlockedMessage(uint32 spell_id, const glm::vec3& location);
|
||||
int GetTotalBlockedSpells() { return totalBS; }
|
||||
inline bool BuffTimersSuspended() const { return newzone_data.SuspendBuffs != 0; };
|
||||
inline bool HasMap() { return zonemap != nullptr; }
|
||||
inline bool HasWaterMap() { return watermap != nullptr; }
|
||||
|
||||
QGlobalCache *GetQGlobals() { return qGlobals; }
|
||||
QGlobalCache *CreateQGlobals() { qGlobals = new QGlobalCache(); return qGlobals; }
|
||||
void UpdateQGlobal(uint32 qid, QGlobal newGlobal);
|
||||
void DeleteQGlobal(std::string name, uint32 npcID, uint32 charID, uint32 zoneID);
|
||||
|
||||
LinkedList<Spawn2*> spawn2_list;
|
||||
LinkedList<ZonePoint*> zone_point_list;
|
||||
uint32 numzonepoints;
|
||||
|
||||
LinkedList<NPC_Emote_Struct*> NPCEmoteList;
|
||||
|
||||
void LoadTickItems();
|
||||
uint32 GetSpawnKillCount(uint32 in_spawnid);
|
||||
void UpdateHotzone();
|
||||
std::unordered_map<int, item_tick_struct> tick_items;
|
||||
|
||||
inline bool InstantGrids() { return (!initgrids_timer.Enabled()); }
|
||||
inline bool IsStaticZone() { return staticzone; }
|
||||
inline const bool IsInstancePersistent() const { return pers_instance; }
|
||||
inline const char *GetFileName() { return file_name; }
|
||||
inline const char *GetLongName() { return long_name; }
|
||||
inline const char *GetShortName() { return short_name; }
|
||||
inline const uint8 GetZoneType() const { return zone_type; }
|
||||
inline const uint16 GetInstanceVersion() const { return instanceversion; }
|
||||
inline const uint32 &GetMaxClients() { return pMaxClients; }
|
||||
inline const uint32 &graveyard_id() { return pgraveyard_id; }
|
||||
inline const uint32 &graveyard_zoneid() { return pgraveyard_zoneid; }
|
||||
inline const uint32 GetInstanceID() const { return instanceid; }
|
||||
inline const uint32 GetZoneID() const { return zoneid; }
|
||||
inline glm::vec3 GetSafePoint() { return m_SafePoint; }
|
||||
inline glm::vec4 GetGraveyardPoint() { return m_Graveyard; }
|
||||
inline std::vector<int> GetGlobalLootTables(NPC *mob) const { return m_global_loot.GetGlobalLootTables(mob); }
|
||||
inline Timer *GetInstanceTimer() { return Instance_Timer; }
|
||||
inline void AddGlobalLootEntry(GlobalLootEntry &in) { return m_global_loot.AddEntry(in); }
|
||||
inline void ShowZoneGlobalLoot(Client *to) { m_global_loot.ShowZoneGlobalLoot(to); }
|
||||
inline void SetZoneHasCurrentTime(bool time) { zone_has_current_time = time; }
|
||||
inline void ShowNPCGlobalLoot(Client *to, NPC *who) { m_global_loot.ShowNPCGlobalLoot(to, who); }
|
||||
inline void ShowZoneGlobalLoot(Client *to) { m_global_loot.ShowZoneGlobalLoot(to); }
|
||||
int GetTotalBlockedSpells() { return totalBS; }
|
||||
int SaveTempItem(uint32 merchantid, uint32 npcid, uint32 item, int32 charges, bool sold = false);
|
||||
int32 MobsAggroCount() { return aggroedmobs; }
|
||||
|
||||
IPathfinder *pathing;
|
||||
LinkedList<NPC_Emote_Struct *> NPCEmoteList;
|
||||
LinkedList<Spawn2 *> spawn2_list;
|
||||
LinkedList<ZonePoint *> zone_point_list;
|
||||
Map *zonemap;
|
||||
MercTemplate *GetMercTemplate(uint32 template_id);
|
||||
NewZone_Struct newzone_data;
|
||||
QGlobalCache *CreateQGlobals()
|
||||
{
|
||||
qGlobals = new QGlobalCache();
|
||||
return qGlobals;
|
||||
}
|
||||
QGlobalCache *GetQGlobals() { return qGlobals; }
|
||||
SpawnConditionManager spawn_conditions;
|
||||
SpawnGroupList spawn_group_list;
|
||||
|
||||
std::list<AltCurrencyDefinition_Struct> AlternateCurrencies;
|
||||
std::list<InternalVeteranReward> VeteranRewards;
|
||||
std::map<uint32, LDoNTrapTemplate *> ldon_trap_list;
|
||||
std::map<uint32, MercTemplate> merc_templates;
|
||||
std::map<uint32, NPCType *> merctable;
|
||||
std::map<uint32, NPCType *> npctable;
|
||||
std::map<uint32, std::list<LDoNTrapTemplate *> > ldon_trap_entry_list;
|
||||
std::map<uint32, std::list<MerchantList> > merchanttable;
|
||||
std::map<uint32, std::list<MercSpellEntry> > merc_spells_list;
|
||||
std::map<uint32, std::list<MercStanceInfo> > merc_stance_list;
|
||||
std::map<uint32, std::list<TempMerchantList> > tmpmerchanttable;
|
||||
std::map<uint32, std::string> adventure_entry_list_flavor;
|
||||
std::map<uint32, ZoneEXPModInfo> level_exp_mod;
|
||||
|
||||
std::pair<AA::Ability *, AA::Rank *> GetAlternateAdvancementAbilityAndRank(int id, int points_spent);
|
||||
|
||||
std::unordered_map<int, item_tick_struct> tick_items;
|
||||
std::unordered_map<int, std::unique_ptr<AA::Ability>> aa_abilities;
|
||||
std::unordered_map<int, std::unique_ptr<AA::Rank>> aa_ranks;
|
||||
|
||||
time_t weather_timer;
|
||||
Timer spawn2_timer;
|
||||
|
||||
uint8 weather_intensity;
|
||||
uint8 zone_weather;
|
||||
uint8 loglevelvar;
|
||||
uint8 lootvar;
|
||||
uint8 merchantvar;
|
||||
uint8 tradevar;
|
||||
uint32 numzonepoints;
|
||||
uint32 CountAuth();
|
||||
uint32 CountSpawn2();
|
||||
uint32 GetSpawnKillCount(uint32 in_spawnid);
|
||||
uint32 GetTempMerchantQuantity(uint32 NPCID, uint32 Slot);
|
||||
|
||||
void AddAggroMob() { aggroedmobs++; }
|
||||
void AddAuth(ServerZoneIncomingClient_Struct *szic);
|
||||
void ChangeWeather();
|
||||
void ClearBlockedSpells();
|
||||
void ClearNPCTypeCache(int id);
|
||||
void DelAggroMob() { aggroedmobs--; }
|
||||
void DeleteQGlobal(std::string name, uint32 npcID, uint32 charID, uint32 zoneID);
|
||||
void Despawn(uint32 spawngroupID);
|
||||
void DoAdventureActions();
|
||||
void DoAdventureAssassinationCountIncrease();
|
||||
void DoAdventureCountIncrease();
|
||||
void GetMerchantDataForZoneLoad();
|
||||
void GetTimeSync();
|
||||
void LoadAdventureFlavor();
|
||||
void LoadAlternateAdvancement();
|
||||
void LoadAlternateCurrencies();
|
||||
void LoadBlockedSpells(uint32 zoneid);
|
||||
void LoadLDoNTrapEntries();
|
||||
void LoadLDoNTraps();
|
||||
void LoadLevelEXPMods();
|
||||
void LoadMercSpells();
|
||||
void LoadMercTemplates();
|
||||
void LoadNewMerchantData(uint32 merchantid);
|
||||
void LoadNPCEmotes(LinkedList<NPC_Emote_Struct *> *NPCEmoteList);
|
||||
void LoadTempMerchantData();
|
||||
void LoadTickItems();
|
||||
void LoadVeteranRewards();
|
||||
void LoadZoneDoors(const char *zone, int16 version);
|
||||
void ReloadStaticData();
|
||||
void ReloadWorld(uint32 Option);
|
||||
void RemoveAuth(const char *iCharName);
|
||||
void Repop(uint32 delay = 0);
|
||||
void RepopClose(const glm::vec4 &client_position, uint32 repop_distance);
|
||||
void RequestUCSServerStatus();
|
||||
void ResetAuth();
|
||||
void SetDate(uint16 year, uint8 month, uint8 day, uint8 hour, uint8 minute);
|
||||
void SetGraveyard(uint32 zoneid, const glm::vec4 &graveyardPosition);
|
||||
void SetInstanceTimer(uint32 new_duration);
|
||||
void SetStaticZone(bool sz) { staticzone = sz; }
|
||||
void SetTime(uint8 hour, uint8 minute, bool update_world = true);
|
||||
void SetUCSServerAvailable(bool ucss_available, uint32 update_timestamp);
|
||||
bool IsUCSServerAvailable() { return m_ucss_available; }
|
||||
void ShowDisabledSpawnStatus(Mob *client);
|
||||
void ShowEnabledSpawnStatus(Mob *client);
|
||||
void ShowSpawnStatusByID(Mob *client, uint32 spawnid);
|
||||
void SpawnConditionChanged(const SpawnCondition &c, int16 old_value);
|
||||
void SpawnStatus(Mob *client);
|
||||
void StartShutdownTimer(uint32 set_time = (RuleI(Zone, AutoShutdownDelay)));
|
||||
void UpdateHotzone();
|
||||
void UpdateQGlobal(uint32 qid, QGlobal newGlobal);
|
||||
void weatherSend(Client *client = nullptr);
|
||||
|
||||
// random object that provides random values for the zone
|
||||
EQEmu::Random random;
|
||||
WaterMap *watermap;
|
||||
ZonePoint *GetClosestZonePoint(const glm::vec3 &location, uint32 to, Client *client, float max_distance = 40000.0f);
|
||||
ZonePoint *GetClosestZonePointWithoutZone(float x, float y, float z, Client *client, float max_distance = 40000.0f);
|
||||
|
||||
static void GMSayHookCallBackProcess(uint16 log_category, std::string message){
|
||||
/* Cut messages down to 4000 max to prevent client crash */
|
||||
if (!message.empty())
|
||||
/**
|
||||
* GMSay Callback for LogSys
|
||||
*
|
||||
* @param log_category
|
||||
* @param message
|
||||
*/
|
||||
static void GMSayHookCallBackProcess(uint16 log_category, std::string message)
|
||||
{
|
||||
/**
|
||||
* Cut messages down to 4000 max to prevent client crash
|
||||
*/
|
||||
if (!message.empty()) {
|
||||
message = message.substr(0, 4000);
|
||||
}
|
||||
|
||||
/* Replace Occurrences of % or MessageStatus will crash */
|
||||
/**
|
||||
* Replace Occurrences of % or MessageStatus will crash
|
||||
*/
|
||||
find_replace(message, std::string("%"), std::string("."));
|
||||
|
||||
if (message.find("\n") != std::string::npos){
|
||||
if (message.find("\n") != std::string::npos) {
|
||||
auto message_split = SplitString(message, '\n');
|
||||
entity_list.MessageStatus(0, 80, LogSys.GetGMSayColorFromCategory(log_category), "%s", message_split[0].c_str());
|
||||
entity_list.MessageStatus(
|
||||
0,
|
||||
80,
|
||||
LogSys.GetGMSayColorFromCategory(log_category),
|
||||
"%s",
|
||||
message_split[0].c_str()
|
||||
);
|
||||
|
||||
for (size_t iter = 1; iter < message_split.size(); ++iter) {
|
||||
entity_list.MessageStatus(0, 80, LogSys.GetGMSayColorFromCategory(log_category), "--- %s", message_split[iter].c_str());
|
||||
entity_list.MessageStatus(
|
||||
0,
|
||||
80,
|
||||
LogSys.GetGMSayColorFromCategory(log_category),
|
||||
"--- %s",
|
||||
message_split[iter].c_str()
|
||||
);
|
||||
}
|
||||
}
|
||||
else{
|
||||
else {
|
||||
entity_list.MessageStatus(0, 80, LogSys.GetGMSayColorFromCategory(log_category), "%s", message.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
//MODDING HOOKS
|
||||
double GetMaxMovementUpdateRange() const { return max_movement_update_range; }
|
||||
|
||||
/**
|
||||
* Modding hooks
|
||||
*/
|
||||
void mod_init();
|
||||
void mod_repop();
|
||||
|
||||
private:
|
||||
uint32 zoneid;
|
||||
uint32 instanceid;
|
||||
uint16 instanceversion;
|
||||
bool pers_instance;
|
||||
char* short_name;
|
||||
char file_name[16];
|
||||
char* long_name;
|
||||
char* map_name;
|
||||
bool pvpzone;
|
||||
bool allow_mercs;
|
||||
bool can_bind;
|
||||
bool can_castoutdoor;
|
||||
bool can_combat;
|
||||
bool can_levitate;
|
||||
bool is_city;
|
||||
bool is_hotzone;
|
||||
bool pers_instance;
|
||||
bool pvpzone;
|
||||
bool m_ucss_available;
|
||||
bool staticzone;
|
||||
bool zone_has_current_time;
|
||||
double max_movement_update_range;
|
||||
char *long_name;
|
||||
char *map_name;
|
||||
char *short_name;
|
||||
char file_name[16];
|
||||
glm::vec3 m_SafePoint;
|
||||
uint32 pMaxClients;
|
||||
bool can_bind;
|
||||
bool is_city;
|
||||
bool can_combat;
|
||||
bool can_castoutdoor;
|
||||
bool can_levitate;
|
||||
bool is_hotzone;
|
||||
uint8 zone_type;
|
||||
bool allow_mercs;
|
||||
uint32 pgraveyard_id, pgraveyard_zoneid;
|
||||
glm::vec4 m_Graveyard;
|
||||
int default_ruleset;
|
||||
int default_ruleset;
|
||||
int totalBS;
|
||||
int32 aggroedmobs;
|
||||
uint8 zone_type;
|
||||
uint16 instanceversion;
|
||||
uint32 instanceid;
|
||||
uint32 pgraveyard_id, pgraveyard_zoneid;
|
||||
uint32 pMaxClients;
|
||||
uint32 zoneid;
|
||||
uint32 m_last_ucss_update;
|
||||
uint32 pQueuedMerchantsWorkID;
|
||||
uint32 pQueuedTempMerchantsWorkID;
|
||||
|
||||
int totalBS;
|
||||
ZoneSpellsBlocked *blocked_spells;
|
||||
GlobalLootManager m_global_loot;
|
||||
LinkedList<ZoneClientAuth_Struct *> client_auth_list;
|
||||
MobMovementManager *mMovementManager;
|
||||
QGlobalCache *qGlobals;
|
||||
Timer *Instance_Shutdown_Timer;
|
||||
Timer *Instance_Timer;
|
||||
Timer *Instance_Warning_timer;
|
||||
Timer *Weather_Timer;
|
||||
Timer autoshutdown_timer;
|
||||
Timer clientauth_timer;
|
||||
Timer hotzone_timer;
|
||||
Timer initgrids_timer; //delayed loading of initial grids.
|
||||
Timer qglobal_purge_timer;
|
||||
ZoneSpellsBlocked *blocked_spells;
|
||||
|
||||
/*
|
||||
Spawn related things
|
||||
*/
|
||||
int32 aggroedmobs;
|
||||
Timer initgrids_timer; //delayed loading of initial grids.
|
||||
|
||||
|
||||
bool staticzone;
|
||||
bool zone_has_current_time;
|
||||
|
||||
uint32 pQueuedMerchantsWorkID;
|
||||
uint32 pQueuedTempMerchantsWorkID;
|
||||
|
||||
Timer autoshutdown_timer;
|
||||
Timer clientauth_timer;
|
||||
Timer qglobal_purge_timer;
|
||||
Timer* Weather_Timer;
|
||||
Timer* Instance_Timer;
|
||||
Timer* Instance_Shutdown_Timer;
|
||||
Timer* Instance_Warning_timer;
|
||||
LinkedList<ZoneClientAuth_Struct*> client_auth_list;
|
||||
QGlobalCache *qGlobals;
|
||||
|
||||
Timer hotzone_timer;
|
||||
|
||||
GlobalLootManager m_global_loot;
|
||||
|
||||
bool m_ucss_available;
|
||||
uint32 m_last_ucss_update;
|
||||
|
||||
MobMovementManager *mMovementManager;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Regular → Executable
+69
-18
@@ -80,7 +80,21 @@ bool ZoneDatabase::SaveZoneCFG(uint32 zoneid, uint16 instance_id, NewZone_Struct
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ZoneDatabase::GetZoneCFG(uint32 zoneid, uint16 instance_id, NewZone_Struct *zone_data, bool &can_bind, bool &can_combat, bool &can_levitate, bool &can_castoutdoor, bool &is_city, bool &is_hotzone, bool &allow_mercs, uint8 &zone_type, int &ruleset, char **map_filename) {
|
||||
bool ZoneDatabase::GetZoneCFG(
|
||||
uint32 zoneid,
|
||||
uint16 instance_id,
|
||||
NewZone_Struct *zone_data,
|
||||
bool &can_bind,
|
||||
bool &can_combat,
|
||||
bool &can_levitate,
|
||||
bool &can_castoutdoor,
|
||||
bool &is_city,
|
||||
bool &is_hotzone,
|
||||
bool &allow_mercs,
|
||||
double &max_movement_update_range,
|
||||
uint8 &zone_type,
|
||||
int &ruleset,
|
||||
char **map_filename) {
|
||||
|
||||
*map_filename = new char[100];
|
||||
zone_data->zone_id = zoneid;
|
||||
@@ -147,7 +161,8 @@ bool ZoneDatabase::GetZoneCFG(uint32 zoneid, uint16 instance_id, NewZone_Struct
|
||||
"fast_regen_hp, " // 57
|
||||
"fast_regen_mana, " // 58
|
||||
"fast_regen_endurance, " // 59
|
||||
"npc_max_aggro_dist " // 60
|
||||
"npc_max_aggro_dist, " // 60
|
||||
"max_movement_update_range " // 61
|
||||
"FROM zone WHERE zoneidnumber = %i AND version = %i",
|
||||
zoneid, instance_id);
|
||||
auto results = QueryDatabase(query);
|
||||
@@ -206,7 +221,7 @@ bool ZoneDatabase::GetZoneCFG(uint32 zoneid, uint16 instance_id, NewZone_Struct
|
||||
can_levitate = atoi(row[33]) == 0 ? false : true;
|
||||
can_castoutdoor = atoi(row[34]) == 0 ? false : true;
|
||||
is_hotzone = atoi(row[35]) == 0 ? false : true;
|
||||
|
||||
max_movement_update_range = atof(row[61]);
|
||||
|
||||
ruleset = atoi(row[36]);
|
||||
zone_data->SuspendBuffs = atoi(row[37]);
|
||||
@@ -1225,17 +1240,28 @@ bool ZoneDatabase::LoadCharacterSpellBook(uint32 character_id, PlayerProfile_Str
|
||||
"`character_spells` "
|
||||
"WHERE `id` = %u ORDER BY `slot_id`", character_id);
|
||||
auto results = database.QueryDatabase(query);
|
||||
int i = 0;
|
||||
|
||||
/* Initialize Spells */
|
||||
for (i = 0; i < EQEmu::spells::SPELLBOOK_SIZE; i++){
|
||||
pp->spell_book[i] = 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
memset(pp->spell_book, 0xFF, (sizeof(uint32) * EQEmu::spells::SPELLBOOK_SIZE));
|
||||
|
||||
// We have the ability to block loaded spells by max id on a per-client basis..
|
||||
// but, we do not have to ability to keep players from using older clients after
|
||||
// they have scribed spells on a newer one that exceeds the older one's limit.
|
||||
// Load them all so that server actions are valid..but, nix them in translators.
|
||||
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
i = atoi(row[0]);
|
||||
if (i < EQEmu::spells::SPELLBOOK_SIZE && atoi(row[1]) <= SPDAT_RECORDS){
|
||||
pp->spell_book[i] = atoi(row[1]);
|
||||
}
|
||||
int idx = atoi(row[0]);
|
||||
int id = atoi(row[1]);
|
||||
|
||||
if (idx < 0 || idx >= EQEmu::spells::SPELLBOOK_SIZE)
|
||||
continue;
|
||||
if (id < 3 || id > SPDAT_RECORDS) // 3 ("Summon Corpse") is the first scribable spell in spells_us.txt
|
||||
continue;
|
||||
|
||||
pp->spell_book[idx] = id;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2472,7 +2498,8 @@ const NPCType* ZoneDatabase::LoadNPCTypesData(uint32 npc_type_id, bool bulk_load
|
||||
"npc_types.charm_atk, "
|
||||
"npc_types.skip_global_loot, "
|
||||
"npc_types.rare_spawn, "
|
||||
"npc_types.stuck_behavior "
|
||||
"npc_types.stuck_behavior, "
|
||||
"npc_types.model "
|
||||
"FROM npc_types %s",
|
||||
where_condition.c_str()
|
||||
);
|
||||
@@ -2662,6 +2689,8 @@ const NPCType* ZoneDatabase::LoadNPCTypesData(uint32 npc_type_id, bool bulk_load
|
||||
temp_npctype_data->skip_global_loot = atoi(row[107]) != 0;
|
||||
temp_npctype_data->rare_spawn = atoi(row[108]) != 0;
|
||||
temp_npctype_data->stuck_behavior = atoi(row[109]);
|
||||
temp_npctype_data->use_model = atoi(row[110]);
|
||||
temp_npctype_data->skip_auto_scale = false; // hardcoded here for now
|
||||
|
||||
// If NPC with duplicate NPC id already in table,
|
||||
// free item we attempted to add.
|
||||
@@ -2864,6 +2893,8 @@ const NPCType* ZoneDatabase::GetMercType(uint32 id, uint16 raceid, uint32 client
|
||||
tmpNPCType->scalerate = atoi(row[43]);
|
||||
tmpNPCType->spellscale = atoi(row[44]);
|
||||
tmpNPCType->healscale = atoi(row[45]);
|
||||
tmpNPCType->skip_global_loot = true;
|
||||
tmpNPCType->skip_auto_scale = true;
|
||||
|
||||
// If Merc with duplicate NPC id already in table,
|
||||
// free item we attempted to add.
|
||||
@@ -3903,6 +3934,8 @@ bool ZoneDatabase::GetFactionData(FactionMods* fm, uint32 class_mod, uint32 race
|
||||
}
|
||||
|
||||
fm->base = faction_array[faction_id]->base;
|
||||
fm->min = faction_array[faction_id]->min; // The lowest your personal earned faction can go - before race/class/diety adjustments.
|
||||
fm->max = faction_array[faction_id]->max; // The highest your personal earned faction can go - before race/class/diety adjustments.
|
||||
|
||||
if(class_mod > 0) {
|
||||
char str[32];
|
||||
@@ -4049,14 +4082,32 @@ bool ZoneDatabase::LoadFactionData()
|
||||
faction_array[index] = new Faction;
|
||||
strn0cpy(faction_array[index]->name, row[1], 50);
|
||||
faction_array[index]->base = atoi(row[2]);
|
||||
faction_array[index]->min = MIN_PERSONAL_FACTION;
|
||||
faction_array[index]->max = MAX_PERSONAL_FACTION;
|
||||
|
||||
query = StringFormat("SELECT `mod`, `mod_name` FROM `faction_list_mod` WHERE faction_id = %u", index);
|
||||
auto modResults = QueryDatabase(query);
|
||||
if (!modResults.Success())
|
||||
continue;
|
||||
// Load in the mimimum and maximum faction that can be earned for this faction
|
||||
query = StringFormat("SELECT `min` , `max` FROM `faction_base_data` WHERE client_faction_id = %u", index);
|
||||
auto baseResults = QueryDatabase(query);
|
||||
if (!baseResults.Success() || baseResults.RowCount() == 0) {
|
||||
Log(Logs::General, Logs::General, "Faction %d has no base data", (int)index);
|
||||
}
|
||||
else {
|
||||
for (auto modRow = baseResults.begin(); modRow != baseResults.end(); ++modRow) {
|
||||
faction_array[index]->min = atoi(modRow[0]);
|
||||
faction_array[index]->max = atoi(modRow[1]);
|
||||
Log(Logs::General, Logs::None, "Min(%d), Max(%d) for faction (%u)",faction_array[index]->min, faction_array[index]->max, index);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto modRow = modResults.begin(); modRow != modResults.end(); ++modRow)
|
||||
faction_array[index]->mods[modRow[1]] = atoi(modRow[0]);
|
||||
// Load in modifiers to the faction based on characters race, class and diety.
|
||||
query = StringFormat("SELECT `mod`, `mod_name` FROM `faction_list_mod` WHERE faction_id = %u", index);
|
||||
auto modResults = QueryDatabase(query);
|
||||
if (!modResults.Success())
|
||||
continue;
|
||||
|
||||
for (auto modRow = modResults.begin(); modRow != modResults.end(); ++modRow) {
|
||||
faction_array[index]->mods[modRow[1]] = atoi(modRow[0]);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
+24
-1
@@ -11,6 +11,10 @@
|
||||
#include "aa_ability.h"
|
||||
#include "event_codes.h"
|
||||
|
||||
#ifdef BOTS
|
||||
#include "bot_database.h"
|
||||
#endif
|
||||
|
||||
class Client;
|
||||
class Corpse;
|
||||
class Merc;
|
||||
@@ -382,7 +386,21 @@ public:
|
||||
bool LoadAlternateAdvancement(Client *c);
|
||||
|
||||
/* Zone related */
|
||||
bool GetZoneCFG(uint32 zoneid, uint16 instance_id, NewZone_Struct *data, bool &can_bind, bool &can_combat, bool &can_levitate, bool &can_castoutdoor, bool &is_city, bool &is_hotzone, bool &allow_mercs, uint8 &zone_type, int &ruleset, char **map_filename);
|
||||
bool GetZoneCFG(
|
||||
uint32 zoneid,
|
||||
uint16 instance_id,
|
||||
NewZone_Struct *data,
|
||||
bool &can_bind,
|
||||
bool &can_combat,
|
||||
bool &can_levitate,
|
||||
bool &can_castoutdoor,
|
||||
bool &is_city,
|
||||
bool &is_hotzone,
|
||||
bool &allow_mercs,
|
||||
double &max_movement_update_range,
|
||||
uint8 &zone_type,
|
||||
int &ruleset,
|
||||
char **map_filename);
|
||||
bool SaveZoneCFG(uint32 zoneid, uint16 instance_id, NewZone_Struct* zd);
|
||||
bool LoadStaticZonePoints(LinkedList<ZonePoint*>* zone_point_list,const char* zonename, uint32 version);
|
||||
bool UpdateZoneSafeCoords(const char* zonename, const glm::vec3& location);
|
||||
@@ -535,6 +553,11 @@ public:
|
||||
/* Things which really dont belong here... */
|
||||
int16 CommandRequirement(const char* commandname);
|
||||
|
||||
#ifdef BOTS
|
||||
// bot database add-on to eliminate the need for a second database connection
|
||||
BotDatabase botdb;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
void ZDBInitVars();
|
||||
|
||||
|
||||
@@ -143,7 +143,9 @@ struct NPCType
|
||||
bool untargetable;
|
||||
bool skip_global_loot;
|
||||
bool rare_spawn;
|
||||
bool skip_auto_scale; // just so it doesn't mess up bots or mercs, probably should add to DB too just in case
|
||||
int8 stuck_behavior;
|
||||
uint16 use_model;
|
||||
};
|
||||
|
||||
namespace player_lootitem {
|
||||
|
||||
Reference in New Issue
Block a user