mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-29 23:15:45 +00:00
Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 18bb202519 | |||
| 49d483bf9c | |||
| 39bb8d92da | |||
| f8712b8baf | |||
| 75a11552fc | |||
| bcd943a964 | |||
| 56608e84bd | |||
| 8d23e710ce | |||
| 4d11077b21 | |||
| 5c0bdfdc4c | |||
| 6130e10831 |
+17
-1
@@ -1,4 +1,20 @@
|
||||
## [22.56.1] 9/13/2024
|
||||
## [22.56.3] 9/23/2024
|
||||
|
||||
### Fixes
|
||||
|
||||
* Fix issue with Client::SaveDisciplines() not specifying character ID ([#4481](https://github.com/EQEmu/Server/pull/4477)) @Kinglykrab 2024-09-23
|
||||
|
||||
## [22.56.2] 9/20/2024
|
||||
|
||||
### Fixes
|
||||
|
||||
* Fix Issue with Database::ReserveName ([#4477](https://github.com/EQEmu/Server/pull/4477)) @Kinglykrab 2024-09-20
|
||||
|
||||
### Quest API
|
||||
|
||||
* Add GrantAllAAPoints() Overload To Perl/Lua ([#4474](https://github.com/EQEmu/Server/pull/4474)) @Kinglykrab 2024-09-20
|
||||
|
||||
## [22.56.1] 9/20/2024
|
||||
|
||||
### Fixes
|
||||
|
||||
|
||||
@@ -482,3 +482,4 @@ ENDIF(EQEMU_BUILD_TESTS)
|
||||
IF(EQEMU_BUILD_CLIENT_FILES)
|
||||
ADD_SUBDIRECTORY(client_files)
|
||||
ENDIF(EQEMU_BUILD_CLIENT_FILES)
|
||||
|
||||
|
||||
@@ -542,7 +542,6 @@ SET(common_headers
|
||||
eqemu_config.h
|
||||
eqemu_config_elements.h
|
||||
eqemu_logsys.h
|
||||
eqemu_logsys_log_aliases.h
|
||||
eq_limits.h
|
||||
eq_packet.h
|
||||
eq_stream_ident.h
|
||||
@@ -803,8 +802,13 @@ IF (UNIX)
|
||||
SET_SOURCE_FILES_PROPERTIES("patches/sod.cpp" "patches/sof.cpp" "patches/rof.cpp" "patches/rof2.cpp" "patches/uf.cpp" PROPERTIES COMPILE_FLAGS -O0)
|
||||
ENDIF (UNIX)
|
||||
|
||||
IF (WIN32 AND EQEMU_BUILD_PCH)
|
||||
TARGET_PRECOMPILE_HEADERS(common PRIVATE pch/pch.h)
|
||||
IF (EQEMU_BUILD_PCH)
|
||||
TARGET_PRECOMPILE_HEADERS(common PRIVATE pch/pch-emu-common.h)
|
||||
TARGET_PRECOMPILE_HEADERS(common PRIVATE pch/pch-containers.h)
|
||||
TARGET_PRECOMPILE_HEADERS(common PRIVATE pch/pch-utilities.h)
|
||||
TARGET_PRECOMPILE_HEADERS(common PRIVATE pch/pch-types.h)
|
||||
TARGET_PRECOMPILE_HEADERS(common PRIVATE pch/pch-fmt.h)
|
||||
# TARGET_PRECOMPILE_HEADERS(common PRIVATE pch/pch-repositories.h)
|
||||
ENDIF ()
|
||||
|
||||
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
|
||||
|
||||
+1
-1
@@ -1860,7 +1860,7 @@ bool Database::CopyCharacter(
|
||||
|
||||
const int64 new_character_id = (CharacterDataRepository::GetMaxId(*this) + 1);
|
||||
|
||||
std::vector<std::string> tables_to_zero_id = { "keyring", "data_buckets" };
|
||||
std::vector<std::string> tables_to_zero_id = { "keyring", "data_buckets", "character_instance_safereturns" };
|
||||
|
||||
TransactionBegin();
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
#include "bodytypes.h"
|
||||
#include "data_verification.h"
|
||||
#include "eqemu_logsys.h"
|
||||
#include "eqemu_logsys_log_aliases.h"
|
||||
#include "rulesys.h"
|
||||
|
||||
int16 EQ::invtype::GetInvTypeSize(int16 inv_type) {
|
||||
|
||||
@@ -246,7 +246,7 @@ namespace Logs {
|
||||
};
|
||||
}
|
||||
|
||||
#include "eqemu_logsys_log_aliases.h"
|
||||
#include "eqemu_logsys_log_aliases.cpp"
|
||||
|
||||
class Database;
|
||||
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef EQEMU_EQEMU_LOGSYS_LOG_ALIASES_H
|
||||
#define EQEMU_EQEMU_LOGSYS_LOG_ALIASES_H
|
||||
#ifndef EQEMU_EQEMU_LOGSYS_LOG_ALIASES_CPP
|
||||
#define EQEMU_EQEMU_LOGSYS_LOG_ALIASES_CPP
|
||||
|
||||
#define LogAA(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::AA))\
|
||||
@@ -855,4 +855,4 @@
|
||||
} while (0)
|
||||
|
||||
|
||||
#endif //EQEMU_EQEMU_LOGSYS_LOG_ALIASES_H
|
||||
#endif //EQEMU_EQEMU_LOGSYS_LOG_ALIASES_CPP
|
||||
@@ -0,0 +1,13 @@
|
||||
#ifndef EQEMU_CONTAINERS_PCH_H
|
||||
#define EQEMU_CONTAINERS_PCH_H
|
||||
|
||||
// containers
|
||||
#include <iterator>
|
||||
#include <set>
|
||||
#include <unordered_set>
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
#include <list>
|
||||
#include <vector>
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,20 @@
|
||||
#ifndef EQEMU_EMU_COMMON_PCH_H
|
||||
#define EQEMU_EMU_COMMON_PCH_H
|
||||
|
||||
#include "mysql.h"
|
||||
|
||||
// emu
|
||||
#include "../../common/types.h"
|
||||
#include "../../common/database.h"
|
||||
#include "../../common/timer.h"
|
||||
#include "../../common/strings.h"
|
||||
#include "../../common/http/httplib.h"
|
||||
#include "../../common/base_packet.h"
|
||||
#include "../../common/database.h"
|
||||
#include "../../common/emu_constants.h"
|
||||
#include "../../common/servertalk.h"
|
||||
#include "../../common/global_define.h"
|
||||
#include "../../common/eqemu_logsys.h"
|
||||
#include "../../common/linked_list.h"
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,9 @@
|
||||
#ifndef EQEMU_FMT_PCH_H
|
||||
#define EQEMU_FMT_PCH_H
|
||||
|
||||
// fmt
|
||||
#include <fmt/format.h>
|
||||
#include <fmt/core.h>
|
||||
#include <cereal/archives/json.hpp>
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,229 @@
|
||||
#ifndef EQEMU_REPOSITORIES_PCH_H
|
||||
#define EQEMU_REPOSITORIES_PCH_H
|
||||
|
||||
#include "../../common/repositories/discovered_items_repository.h"
|
||||
#include "../../common/repositories/lootdrop_repository.h"
|
||||
#include "../../common/repositories/spells_new_repository.h"
|
||||
#include "../../common/repositories/aa_rank_effects_repository.h"
|
||||
#include "../../common/repositories/titles_repository.h"
|
||||
#include "../../common/repositories/character_bandolier_repository.h"
|
||||
#include "../../common/repositories/completed_shared_tasks_repository.h"
|
||||
#include "../../common/repositories/faction_list_mod_repository.h"
|
||||
#include "../../common/repositories/merc_templates_repository.h"
|
||||
#include "../../common/repositories/spawngroup_repository.h"
|
||||
#include "../../common/repositories/character_bind_repository.h"
|
||||
#include "../../common/repositories/npc_types_tint_repository.h"
|
||||
#include "../../common/repositories/merc_armorinfo_repository.h"
|
||||
#include "../../common/repositories/adventure_template_entry_flavor_repository.h"
|
||||
#include "../../common/repositories/character_pet_info_repository.h"
|
||||
#include "../../common/repositories/raid_details_repository.h"
|
||||
#include "../../common/repositories/guild_tributes_repository.h"
|
||||
#include "../../common/repositories/tasksets_repository.h"
|
||||
#include "../../common/repositories/character_inspect_messages_repository.h"
|
||||
#include "../../common/repositories/merc_spell_list_entries_repository.h"
|
||||
#include "../../common/repositories/npc_types_repository.h"
|
||||
#include "../../common/repositories/bot_buffs_repository.h"
|
||||
#include "../../common/repositories/shared_task_activity_state_repository.h"
|
||||
#include "../../common/repositories/forage_repository.h"
|
||||
#include "../../common/repositories/global_loot_repository.h"
|
||||
#include "../../common/repositories/adventure_members_repository.h"
|
||||
#include "../../common/repositories/merc_subtypes_repository.h"
|
||||
#include "../../common/repositories/aa_ranks_repository.h"
|
||||
#include "../../common/repositories/character_auras_repository.h"
|
||||
#include "../../common/repositories/loottable_repository.h"
|
||||
#include "../../common/repositories/bot_timers_repository.h"
|
||||
#include "../../common/repositories/graveyard_repository.h"
|
||||
#include "../../common/repositories/expedition_lockouts_repository.h"
|
||||
#include "../../common/repositories/bot_group_members_repository.h"
|
||||
#include "../../common/repositories/spawn_conditions_repository.h"
|
||||
#include "../../common/repositories/character_disciplines_repository.h"
|
||||
#include "../../common/repositories/npc_faction_entries_repository.h"
|
||||
#include "../../common/repositories/pets_equipmentset_entries_repository.h"
|
||||
#include "../../common/repositories/bot_inspect_messages_repository.h"
|
||||
#include "../../common/repositories/char_create_combinations_repository.h"
|
||||
#include "../../common/repositories/guild_ranks_repository.h"
|
||||
#include "../../common/repositories/character_stats_record_repository.h"
|
||||
#include "../../common/repositories/adventure_stats_repository.h"
|
||||
#include "../../common/repositories/buyer_trade_items_repository.h"
|
||||
#include "../../common/repositories/buyer_buy_lines_repository.h"
|
||||
#include "../../common/repositories/timers_repository.h"
|
||||
#include "../../common/repositories/lfguild_repository.h"
|
||||
#include "../../common/repositories/character_potionbelt_repository.h"
|
||||
#include "../../common/repositories/ground_spawns_repository.h"
|
||||
#include "../../common/repositories/npc_spells_effects_repository.h"
|
||||
#include "../../common/repositories/guild_relations_repository.h"
|
||||
#include "../../common/repositories/merc_stats_repository.h"
|
||||
#include "../../common/repositories/petitions_repository.h"
|
||||
#include "../../common/repositories/chatchannels_repository.h"
|
||||
#include "../../common/repositories/character_parcels_repository.h"
|
||||
#include "../../common/repositories/zone_flags_repository.h"
|
||||
#include "../../common/repositories/merc_merchant_templates_repository.h"
|
||||
#include "../../common/repositories/criteria/content_filter_criteria.h"
|
||||
#include "../../common/repositories/login_server_admins_repository.h"
|
||||
#include "../../common/repositories/character_pet_inventory_repository.h"
|
||||
#include "../../common/repositories/merc_name_types_repository.h"
|
||||
#include "../../common/repositories/character_peqzone_flags_repository.h"
|
||||
#include "../../common/repositories/spawnentry_repository.h"
|
||||
#include "../../common/repositories/player_titlesets_repository.h"
|
||||
#include "../../common/repositories/gm_ips_repository.h"
|
||||
#include "../../common/repositories/character_spells_repository.h"
|
||||
#include "../../common/repositories/rule_sets_repository.h"
|
||||
#include "../../common/repositories/character_alt_currency_repository.h"
|
||||
#include "../../common/repositories/aa_ability_repository.h"
|
||||
#include "../../common/repositories/command_subsettings_repository.h"
|
||||
#include "../../common/repositories/items_repository.h"
|
||||
#include "../../common/repositories/login_api_tokens_repository.h"
|
||||
#include "../../common/repositories/bot_stances_repository.h"
|
||||
#include "../../common/repositories/spell_globals_repository.h"
|
||||
#include "../../common/repositories/pets_equipmentset_repository.h"
|
||||
#include "../../common/repositories/starting_items_repository.h"
|
||||
#include "../../common/repositories/bot_create_combinations_repository.h"
|
||||
#include "../../common/repositories/inventory_snapshots_repository.h"
|
||||
#include "../../common/repositories/ldon_trap_templates_repository.h"
|
||||
#include "../../common/repositories/guild_members_repository.h"
|
||||
#include "../../common/repositories/expeditions_repository.h"
|
||||
#include "../../common/repositories/level_exp_mods_repository.h"
|
||||
#include "../../common/repositories/pets_beastlord_data_repository.h"
|
||||
#include "../../common/repositories/merc_stance_entries_repository.h"
|
||||
#include "../../common/repositories/doors_repository.h"
|
||||
#include "../../common/repositories/tool_game_objects_repository.h"
|
||||
#include "../../common/repositories/npc_spells_entries_repository.h"
|
||||
#include "../../common/repositories/bot_heal_rotation_targets_repository.h"
|
||||
#include "../../common/repositories/shared_tasks_repository.h"
|
||||
#include "../../common/repositories/tradeskill_recipe_repository.h"
|
||||
#include "../../common/repositories/char_create_point_allocations_repository.h"
|
||||
#include "../../common/repositories/bot_spells_entries_repository.h"
|
||||
#include "../../common/repositories/raid_members_repository.h"
|
||||
#include "../../common/repositories/character_languages_repository.h"
|
||||
#include "../../common/repositories/merchantlist_repository.h"
|
||||
#include "../../common/repositories/object_repository.h"
|
||||
#include "../../common/repositories/login_world_servers_repository.h"
|
||||
#include "../../common/repositories/character_parcels_containers_repository.h"
|
||||
#include "../../common/repositories/bot_starting_items_repository.h"
|
||||
#include "../../common/repositories/adventure_template_entry_repository.h"
|
||||
#include "../../common/repositories/alternate_currency_repository.h"
|
||||
#include "../../common/repositories/tributes_repository.h"
|
||||
#include "../../common/repositories/bug_reports_repository.h"
|
||||
#include "../../common/repositories/account_repository.h"
|
||||
#include "../../common/repositories/quest_globals_repository.h"
|
||||
#include "../../common/repositories/merc_types_repository.h"
|
||||
#include "../../common/repositories/completed_tasks_repository.h"
|
||||
#include "../../common/repositories/object_contents_repository.h"
|
||||
#include "../../common/repositories/dynamic_zone_members_repository.h"
|
||||
#include "../../common/repositories/aa_rank_prereqs_repository.h"
|
||||
#include "../../common/repositories/bot_pet_buffs_repository.h"
|
||||
#include "../../common/repositories/character_activities_repository.h"
|
||||
#include "../../common/repositories/character_corpse_items_repository.h"
|
||||
#include "../../common/repositories/spawn2_repository.h"
|
||||
#include "../../common/repositories/bot_owner_options_repository.h"
|
||||
#include "../../common/repositories/bot_heal_rotations_repository.h"
|
||||
#include "../../common/repositories/content_flags_repository.h"
|
||||
#include "../../common/repositories/ip_exemptions_repository.h"
|
||||
#include "../../common/repositories/completed_shared_task_members_repository.h"
|
||||
#include "../../common/repositories/character_material_repository.h"
|
||||
#include "../../common/repositories/grid_repository.h"
|
||||
#include "../../common/repositories/db_str_repository.h"
|
||||
#include "../../common/repositories/character_skills_repository.h"
|
||||
#include "../../common/repositories/guild_bank_repository.h"
|
||||
#include "../../common/repositories/reports_repository.h"
|
||||
#include "../../common/repositories/instance_list_player_repository.h"
|
||||
#include "../../common/repositories/character_tribute_repository.h"
|
||||
#include "../../common/repositories/ldon_trap_entries_repository.h"
|
||||
#include "../../common/repositories/bot_pets_repository.h"
|
||||
#include "../../common/repositories/merc_buffs_repository.h"
|
||||
#include "../../common/repositories/skill_caps_repository.h"
|
||||
#include "../../common/repositories/character_data_repository.h"
|
||||
#include "../../common/repositories/account_ip_repository.h"
|
||||
#include "../../common/repositories/traps_repository.h"
|
||||
#include "../../common/repositories/dynamic_zone_templates_repository.h"
|
||||
#include "../../common/repositories/mail_repository.h"
|
||||
#include "../../common/repositories/group_leaders_repository.h"
|
||||
#include "../../common/repositories/respawn_times_repository.h"
|
||||
#include "../../common/repositories/task_activities_repository.h"
|
||||
#include "../../common/repositories/blocked_spells_repository.h"
|
||||
#include "../../common/repositories/rule_values_repository.h"
|
||||
#include "../../common/repositories/tradeskill_recipe_entries_repository.h"
|
||||
#include "../../common/repositories/spawn_events_repository.h"
|
||||
#include "../../common/repositories/player_event_log_settings_repository.h"
|
||||
#include "../../common/repositories/completed_shared_task_activity_state_repository.h"
|
||||
#include "../../common/repositories/inventory_repository.h"
|
||||
#include "../../common/repositories/perl_event_export_settings_repository.h"
|
||||
#include "../../common/repositories/zone_points_repository.h"
|
||||
#include "../../common/repositories/character_memmed_spells_repository.h"
|
||||
#include "../../common/repositories/spawn_condition_values_repository.h"
|
||||
#include "../../common/repositories/login_server_list_types_repository.h"
|
||||
#include "../../common/repositories/npc_emotes_repository.h"
|
||||
#include "../../common/repositories/veteran_reward_templates_repository.h"
|
||||
#include "../../common/repositories/merc_weaponinfo_repository.h"
|
||||
#include "../../common/repositories/data_buckets_repository.h"
|
||||
#include "../../common/repositories/fishing_repository.h"
|
||||
#include "../../common/repositories/books_repository.h"
|
||||
#include "../../common/repositories/character_alternate_abilities_repository.h"
|
||||
#include "../../common/repositories/bot_spell_casting_chances_repository.h"
|
||||
#include "../../common/repositories/login_accounts_repository.h"
|
||||
#include "../../common/repositories/tribute_levels_repository.h"
|
||||
#include "../../common/repositories/merchantlist_temp_repository.h"
|
||||
#include "../../common/repositories/account_rewards_repository.h"
|
||||
#include "../../common/repositories/lootdrop_entries_repository.h"
|
||||
#include "../../common/repositories/server_scheduled_events_repository.h"
|
||||
#include "../../common/repositories/bot_groups_repository.h"
|
||||
#include "../../common/repositories/shared_task_dynamic_zones_repository.h"
|
||||
#include "../../common/repositories/zone_repository.h"
|
||||
#include "../../common/repositories/horses_repository.h"
|
||||
#include "../../common/repositories/character_pet_buffs_repository.h"
|
||||
#include "../../common/repositories/dynamic_zones_repository.h"
|
||||
#include "../../common/repositories/start_zones_repository.h"
|
||||
#include "../../common/repositories/keyring_repository.h"
|
||||
#include "../../common/repositories/merc_merchant_template_entries_repository.h"
|
||||
#include "../../common/repositories/character_item_recast_repository.h"
|
||||
#include "../../common/repositories/merc_inventory_repository.h"
|
||||
#include "../../common/repositories/merc_npc_types_repository.h"
|
||||
#include "../../common/repositories/pets_repository.h"
|
||||
#include "../../common/repositories/damageshieldtypes_repository.h"
|
||||
#include "../../common/repositories/char_recipe_list_repository.h"
|
||||
#include "../../common/repositories/instance_list_repository.h"
|
||||
#include "../../common/repositories/bot_guild_members_repository.h"
|
||||
#include "../../common/repositories/character_tasks_repository.h"
|
||||
#include "../../common/repositories/npc_spells_effects_entries_repository.h"
|
||||
#include "../../common/repositories/auras_repository.h"
|
||||
#include "../../common/repositories/character_task_timers_repository.h"
|
||||
#include "../../common/repositories/merc_spell_lists_repository.h"
|
||||
#include "../../common/repositories/npc_faction_repository.h"
|
||||
#include "../../common/repositories/friends_repository.h"
|
||||
#include "../../common/repositories/bot_spell_settings_repository.h"
|
||||
#include "../../common/repositories/player_event_logs_repository.h"
|
||||
#include "../../common/repositories/bot_data_repository.h"
|
||||
#include "../../common/repositories/character_leadership_abilities_repository.h"
|
||||
#include "../../common/repositories/grid_entries_repository.h"
|
||||
#include "../../common/repositories/bot_inventories_repository.h"
|
||||
#include "../../common/repositories/tasks_repository.h"
|
||||
#include "../../common/repositories/name_filter_repository.h"
|
||||
#include "../../common/repositories/character_instance_safereturns_repository.h"
|
||||
#include "../../common/repositories/faction_association_repository.h"
|
||||
#include "../../common/repositories/logsys_categories_repository.h"
|
||||
#include "../../common/repositories/buyer_repository.h"
|
||||
#include "../../common/repositories/character_currency_repository.h"
|
||||
#include "../../common/repositories/discord_webhooks_repository.h"
|
||||
#include "../../common/repositories/guild_permissions_repository.h"
|
||||
#include "../../common/repositories/chatchannel_reserved_names_repository.h"
|
||||
#include "../../common/repositories/character_expedition_lockouts_repository.h"
|
||||
#include "../../common/repositories/loottable_entries_repository.h"
|
||||
#include "../../common/repositories/bot_pet_inventories_repository.h"
|
||||
#include "../../common/repositories/npc_spells_repository.h"
|
||||
#include "../../common/repositories/faction_list_repository.h"
|
||||
#include "../../common/repositories/group_id_repository.h"
|
||||
#include "../../common/repositories/character_buffs_repository.h"
|
||||
#include "../../common/repositories/faction_values_repository.h"
|
||||
#include "../../common/repositories/variables_repository.h"
|
||||
#include "../../common/repositories/guilds_repository.h"
|
||||
#include "../../common/repositories/bot_heal_rotation_members_repository.h"
|
||||
#include "../../common/repositories/spell_buckets_repository.h"
|
||||
#include "../../common/repositories/spawn2_disabled_repository.h"
|
||||
#include "../../common/repositories/saylink_repository.h"
|
||||
#include "../../common/repositories/trader_repository.h"
|
||||
#include "../../common/repositories/shared_task_members_repository.h"
|
||||
#include "../../common/repositories/merc_merchant_entries_repository.h"
|
||||
#include "../../common/repositories/character_corpses_repository.h"
|
||||
#include "../../common/repositories/adventure_details_repository.h"
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
#ifndef EQEMU_TYPES_PCH_H
|
||||
#define EQEMU_TYPES_PCH_H
|
||||
|
||||
// types
|
||||
#include <limits>
|
||||
#include <string>
|
||||
#include <cctype>
|
||||
#include <sstream>
|
||||
#include <type_traits>
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,20 @@
|
||||
#ifndef EQEMU_UTILITIES_PCH_H
|
||||
#define EQEMU_UTILITIES_PCH_H
|
||||
|
||||
// utilities
|
||||
#include <iostream>
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
#include <tuple>
|
||||
#include <fstream>
|
||||
#include <chrono>
|
||||
#include <cstdio>
|
||||
#include <stdio.h>
|
||||
#include <mutex>
|
||||
#include <filesystem>
|
||||
|
||||
#endif
|
||||
@@ -1,34 +0,0 @@
|
||||
// types
|
||||
#include <limits>
|
||||
#include <string>
|
||||
#include <cctype>
|
||||
#include <sstream>
|
||||
|
||||
// containers
|
||||
#include <iterator>
|
||||
#include <set>
|
||||
#include <unordered_set>
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
#include <list>
|
||||
#include <vector>
|
||||
|
||||
// utilities
|
||||
#include <iostream>
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
#include <tuple>
|
||||
#include <fstream>
|
||||
#include <cstdio>
|
||||
|
||||
// fmt
|
||||
#include <fmt/format.h>
|
||||
|
||||
// lua
|
||||
#include "lua.hpp"
|
||||
#include <luabind/luabind.hpp>
|
||||
#include <luabind/object.hpp>
|
||||
+1
-1
@@ -25,7 +25,7 @@
|
||||
|
||||
// Build variables
|
||||
// these get injected during the build pipeline
|
||||
#define CURRENT_VERSION "22.56.1-dev" // always append -dev to the current version for custom-builds
|
||||
#define CURRENT_VERSION "22.56.3-dev" // always append -dev to the current version for custom-builds
|
||||
#define LOGIN_VERSION "0.8.0"
|
||||
#define COMPILE_DATE __DATE__
|
||||
#define COMPILE_TIME __TIME__
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "eqemu-server",
|
||||
"version": "22.56.1",
|
||||
"version": "22.56.3",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/EQEmu/Server.git"
|
||||
|
||||
@@ -12,6 +12,7 @@ perl utils/scripts/build/tag-version.pl
|
||||
mkdir -p build && cd build && \
|
||||
cmake -DEQEMU_BUILD_TESTS=ON \
|
||||
-DEQEMU_BUILD_STATIC=ON \
|
||||
-DEQEMU_BUILD_PCH=ON \
|
||||
-DEQEMU_BUILD_LOGIN=ON \
|
||||
-DEQEMU_BUILD_LUA=ON \
|
||||
-DEQEMU_BUILD_PERL=ON \
|
||||
|
||||
@@ -78,8 +78,12 @@ ADD_EXECUTABLE(world ${world_sources} ${world_headers})
|
||||
|
||||
INSTALL(TARGETS world RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
|
||||
|
||||
IF (WIN32 AND EQEMU_BUILD_PCH)
|
||||
TARGET_PRECOMPILE_HEADERS(world PRIVATE ../common/pch/pch.h)
|
||||
IF (EQEMU_BUILD_PCH)
|
||||
TARGET_PRECOMPILE_HEADERS(world PRIVATE ../common/pch/pch-emu-common.h)
|
||||
TARGET_PRECOMPILE_HEADERS(world PRIVATE ../common/pch/pch-containers.h)
|
||||
TARGET_PRECOMPILE_HEADERS(world PRIVATE ../common/pch/pch-utilities.h)
|
||||
TARGET_PRECOMPILE_HEADERS(world PRIVATE ../common/pch/pch-types.h)
|
||||
TARGET_PRECOMPILE_HEADERS(world PRIVATE ../common/pch/pch-fmt.h)
|
||||
ENDIF ()
|
||||
|
||||
ADD_DEFINITIONS(-DWORLD)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "../../common/eqemu_logsys_log_aliases.h"
|
||||
#include "../../common/eqemu_logsys.h"
|
||||
#include "../worlddb.h"
|
||||
|
||||
void WorldserverCLI::CopyCharacter(int argc, char **argv, argh::parser &cmd, std::string &description)
|
||||
|
||||
+8
-4
@@ -289,10 +289,14 @@ ADD_EXECUTABLE(zone ${zone_sources} ${zone_headers})
|
||||
|
||||
INSTALL(TARGETS zone RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
|
||||
|
||||
IF (WIN32 AND EQEMU_BUILD_PCH)
|
||||
TARGET_PRECOMPILE_HEADERS(zone PRIVATE ../common/pch/pch.h)
|
||||
TARGET_PRECOMPILE_HEADERS(zone PRIVATE ../common/types.h ../common/eqemu_logsys.h ../common/eqemu_logsys_log_aliases.h ../common/features.h ../common/global_define.h)
|
||||
TARGET_PRECOMPILE_HEADERS(zone PRIVATE mob.h npc.h corpse.h doors.h bot.h entity.h client.h zone.h)
|
||||
IF (EQEMU_BUILD_PCH)
|
||||
TARGET_PRECOMPILE_HEADERS(zone PRIVATE ../common/pch/pch-emu-common.h)
|
||||
TARGET_PRECOMPILE_HEADERS(zone PRIVATE ../common/pch/pch-containers.h)
|
||||
TARGET_PRECOMPILE_HEADERS(zone PRIVATE ../common/pch/pch-utilities.h)
|
||||
TARGET_PRECOMPILE_HEADERS(zone PRIVATE ../common/pch/pch-types.h)
|
||||
TARGET_PRECOMPILE_HEADERS(zone PRIVATE ../common/pch/pch-fmt.h)
|
||||
# TARGET_PRECOMPILE_HEADERS(zone PRIVATE ../common/pch/pch-repositories.h)
|
||||
TARGET_PRECOMPILE_HEADERS(zone PRIVATE pch/pch.h)
|
||||
ENDIF()
|
||||
|
||||
ADD_DEFINITIONS(-DZONE)
|
||||
|
||||
+3
-5
@@ -1739,7 +1739,7 @@ bool Mob::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool
|
||||
(HasOwner() && GetOwner()->IsClient() && other->IsClient())
|
||||
)
|
||||
) {
|
||||
for (auto const& [id, mob] : entity_list.GetCloseMobList(other)) {
|
||||
for (auto const& [id, mob] : other->GetCloseMobList()) {
|
||||
if (!mob) {
|
||||
continue;
|
||||
}
|
||||
@@ -2319,8 +2319,7 @@ bool NPC::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool
|
||||
//Guard Assist Code
|
||||
if (RuleB(Character, PVPEnableGuardFactionAssist)) {
|
||||
if (IsClient() && other->IsClient() || (HasOwner() && GetOwner()->IsClient() && other->IsClient())) {
|
||||
auto& mob_list = entity_list.GetCloseMobList(other);
|
||||
for (auto& e : mob_list) {
|
||||
for (auto& e : other->GetCloseMobList()) {
|
||||
auto mob = e.second;
|
||||
if (!mob) {
|
||||
continue;
|
||||
@@ -2973,8 +2972,7 @@ bool NPC::Death(Mob* killer_mob, int64 damage, uint16 spell, EQ::skills::SkillTy
|
||||
entity_list.UnMarkNPC(GetID());
|
||||
entity_list.RemoveNPC(GetID());
|
||||
|
||||
// entity_list.RemoveMobFromCloseLists(this);
|
||||
close_mobs.clear();
|
||||
m_close_mobs.clear();
|
||||
SetID(0);
|
||||
ApplyIllusionToCorpse(illusion_spell_id, corpse);
|
||||
|
||||
|
||||
+7
-12
@@ -72,7 +72,7 @@ Mob *Aura::GetOwner()
|
||||
// not 100% sure how this one should work and PVP affects ...
|
||||
void Aura::ProcessOnAllFriendlies(Mob *owner)
|
||||
{
|
||||
auto &mob_list = entity_list.GetCloseMobList(this, distance);
|
||||
auto &mob_list = GetCloseMobList(distance);
|
||||
std::set<int> delayed_remove;
|
||||
bool is_buff = IsBuffSpell(spell_id); // non-buff spells don't cast on enter
|
||||
|
||||
@@ -127,7 +127,7 @@ void Aura::ProcessOnAllFriendlies(Mob *owner)
|
||||
|
||||
void Aura::ProcessOnAllGroupMembers(Mob *owner)
|
||||
{
|
||||
auto &mob_list = entity_list.GetCloseMobList(this, distance);
|
||||
auto &mob_list = GetCloseMobList(distance);
|
||||
std::set<int> delayed_remove;
|
||||
bool is_buff = IsBuffSpell(spell_id); // non-buff spells don't cast on enter
|
||||
|
||||
@@ -369,7 +369,7 @@ void Aura::ProcessOnAllGroupMembers(Mob *owner)
|
||||
|
||||
void Aura::ProcessOnGroupMembersPets(Mob *owner)
|
||||
{
|
||||
auto &mob_list = entity_list.GetCloseMobList(this,distance);
|
||||
auto &mob_list = GetCloseMobList(distance);
|
||||
std::set<int> delayed_remove;
|
||||
bool is_buff = IsBuffSpell(spell_id); // non-buff spells don't cast on enter
|
||||
// This type can either live on the pet (level 55/70 MAG aura) or on the pet owner (level 85 MAG aura)
|
||||
@@ -576,7 +576,7 @@ void Aura::ProcessOnGroupMembersPets(Mob *owner)
|
||||
|
||||
void Aura::ProcessTotem(Mob *owner)
|
||||
{
|
||||
auto &mob_list = entity_list.GetCloseMobList(this, distance);
|
||||
auto &mob_list = GetCloseMobList(distance);
|
||||
std::set<int> delayed_remove;
|
||||
bool is_buff = IsBuffSpell(spell_id); // non-buff spells don't cast on enter
|
||||
|
||||
@@ -634,9 +634,7 @@ void Aura::ProcessTotem(Mob *owner)
|
||||
|
||||
void Aura::ProcessEnterTrap(Mob *owner)
|
||||
{
|
||||
auto &mob_list = entity_list.GetCloseMobList(this, distance);
|
||||
|
||||
for (auto &e : mob_list) {
|
||||
for (auto &e : GetCloseMobList(distance)) {
|
||||
auto mob = e.second;
|
||||
if (!mob) {
|
||||
continue;
|
||||
@@ -656,9 +654,7 @@ void Aura::ProcessEnterTrap(Mob *owner)
|
||||
|
||||
void Aura::ProcessExitTrap(Mob *owner)
|
||||
{
|
||||
auto &mob_list = entity_list.GetCloseMobList(this, distance);
|
||||
|
||||
for (auto &e : mob_list) {
|
||||
for (auto &e : GetCloseMobList(distance)) {
|
||||
auto mob = e.second;
|
||||
if (!mob) {
|
||||
continue;
|
||||
@@ -689,8 +685,7 @@ void Aura::ProcessExitTrap(Mob *owner)
|
||||
// and hard to reason about
|
||||
void Aura::ProcessSpawns()
|
||||
{
|
||||
const auto &clients = entity_list.GetCloseMobList(this, distance);
|
||||
for (auto &e : clients) {
|
||||
for (auto &e: GetCloseMobList(distance)) {
|
||||
if (!e.second) {
|
||||
continue;
|
||||
}
|
||||
|
||||
+2
-12
@@ -1578,17 +1578,7 @@ bool Bot::Process()
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mob_close_scan_timer.Check()) {
|
||||
LogAIScanCloseDetail(
|
||||
"is_moving [{}] bot [{}] timer [{}]",
|
||||
moving ? "true" : "false",
|
||||
GetCleanName(),
|
||||
mob_close_scan_timer.GetDuration()
|
||||
);
|
||||
|
||||
entity_list.ScanCloseMobs(close_mobs, this, IsMoving());
|
||||
}
|
||||
|
||||
ScanCloseMobProcess();
|
||||
SpellProcess();
|
||||
|
||||
if (tic_timer.Check()) {
|
||||
@@ -2978,7 +2968,7 @@ void Bot::SetOwnerTarget(Client* bot_owner) {
|
||||
if (NOT_HOLDING && NOT_PASSIVE) {
|
||||
|
||||
auto attack_target = bot_owner->GetTarget();
|
||||
if (attack_target) {
|
||||
if (attack_target && HasBotAttackFlag(attack_target)) {
|
||||
|
||||
InterruptSpell();
|
||||
WipeHateList();
|
||||
|
||||
@@ -35,6 +35,11 @@ void bot_command_attack(Client *c, const Seperator *sep)
|
||||
return;
|
||||
}
|
||||
|
||||
if (!c->HasBotAttackFlag(target_mob)) {
|
||||
target_mob->SetBotAttackFlag(c->CharacterID());
|
||||
target_mob->bot_attack_flag_timer.Start(10000);
|
||||
}
|
||||
|
||||
size_t attacker_count = 0;
|
||||
Bot *first_attacker = nullptr;
|
||||
sbl.remove(nullptr);
|
||||
|
||||
+144
-62
@@ -145,49 +145,48 @@ Client::Client(EQStreamInterface *ieqs) : Mob(
|
||||
0, // in_heroic_strikethrough
|
||||
false // in_keeps_sold_items
|
||||
),
|
||||
hpupdate_timer(2000),
|
||||
camp_timer(29000),
|
||||
process_timer(100),
|
||||
consume_food_timer(CONSUMPTION_TIMER),
|
||||
zoneinpacket_timer(1000),
|
||||
linkdead_timer(RuleI(Zone,ClientLinkdeadMS)),
|
||||
dead_timer(2000),
|
||||
global_channel_timer(1000),
|
||||
fishing_timer(8000),
|
||||
endupkeep_timer(1000),
|
||||
autosave_timer(RuleI(Character, AutosaveIntervalS) * 1000),
|
||||
client_scan_npc_aggro_timer(RuleI(Aggro, ClientAggroCheckIdleInterval)),
|
||||
client_zone_wide_full_position_update_timer(5 * 60 * 1000),
|
||||
tribute_timer(Tribute_duration),
|
||||
proximity_timer(ClientProximity_interval),
|
||||
TaskPeriodic_Timer(RuleI(TaskSystem, PeriodicCheckTimer) * 1000),
|
||||
charm_update_timer(6000),
|
||||
rest_timer(1),
|
||||
pick_lock_timer(1000),
|
||||
charm_class_attacks_timer(3000),
|
||||
charm_cast_timer(3500),
|
||||
qglobal_purge_timer(30000),
|
||||
TrackingTimer(2000),
|
||||
RespawnFromHoverTimer(0),
|
||||
merc_timer(RuleI(Mercs, UpkeepIntervalMS)),
|
||||
ItemQuestTimer(500),
|
||||
anon_toggle_timer(250),
|
||||
afk_toggle_timer(250),
|
||||
helm_toggle_timer(250),
|
||||
aggro_meter_timer(AGGRO_METER_UPDATE_MS),
|
||||
m_Proximity(FLT_MAX, FLT_MAX, FLT_MAX), //arbitrary large number
|
||||
m_ZoneSummonLocation(-2.0f,-2.0f,-2.0f,-2.0f),
|
||||
m_AutoAttackPosition(0.0f, 0.0f, 0.0f, 0.0f),
|
||||
m_AutoAttackTargetLocation(0.0f, 0.0f, 0.0f),
|
||||
last_region_type(RegionTypeUnsupported),
|
||||
m_dirtyautohaters(false),
|
||||
mob_close_scan_timer(6000),
|
||||
position_update_timer(10000),
|
||||
consent_throttle_timer(2000),
|
||||
tmSitting(0),
|
||||
parcel_timer(RuleI(Parcel, ParcelDeliveryDelay)),
|
||||
lazy_load_bank_check_timer(1000),
|
||||
bandolier_throttle_timer(0)
|
||||
hpupdate_timer(2000),
|
||||
camp_timer(29000),
|
||||
process_timer(100),
|
||||
consume_food_timer(CONSUMPTION_TIMER),
|
||||
zoneinpacket_timer(1000),
|
||||
linkdead_timer(RuleI(Zone, ClientLinkdeadMS)),
|
||||
dead_timer(2000),
|
||||
global_channel_timer(1000),
|
||||
fishing_timer(8000),
|
||||
endupkeep_timer(1000),
|
||||
autosave_timer(RuleI(Character, AutosaveIntervalS) * 1000),
|
||||
m_client_npc_aggro_scan_timer(RuleI(Aggro, ClientAggroCheckIdleInterval)),
|
||||
m_client_zone_wide_full_position_update_timer(5 * 60 * 1000),
|
||||
tribute_timer(Tribute_duration),
|
||||
proximity_timer(ClientProximity_interval),
|
||||
TaskPeriodic_Timer(RuleI(TaskSystem, PeriodicCheckTimer) * 1000),
|
||||
charm_update_timer(6000),
|
||||
rest_timer(1),
|
||||
pick_lock_timer(1000),
|
||||
charm_class_attacks_timer(3000),
|
||||
charm_cast_timer(3500),
|
||||
qglobal_purge_timer(30000),
|
||||
TrackingTimer(2000),
|
||||
RespawnFromHoverTimer(0),
|
||||
merc_timer(RuleI(Mercs, UpkeepIntervalMS)),
|
||||
ItemQuestTimer(500),
|
||||
anon_toggle_timer(250),
|
||||
afk_toggle_timer(250),
|
||||
helm_toggle_timer(250),
|
||||
aggro_meter_timer(AGGRO_METER_UPDATE_MS),
|
||||
m_Proximity(FLT_MAX, FLT_MAX, FLT_MAX), //arbitrary large number
|
||||
m_ZoneSummonLocation(-2.0f, -2.0f, -2.0f, -2.0f),
|
||||
m_AutoAttackPosition(0.0f, 0.0f, 0.0f, 0.0f),
|
||||
m_AutoAttackTargetLocation(0.0f, 0.0f, 0.0f),
|
||||
last_region_type(RegionTypeUnsupported),
|
||||
m_dirtyautohaters(false),
|
||||
m_position_update_timer(10000),
|
||||
consent_throttle_timer(2000),
|
||||
tmSitting(0),
|
||||
parcel_timer(RuleI(Parcel, ParcelDeliveryDelay)),
|
||||
lazy_load_bank_check_timer(1000),
|
||||
bandolier_throttle_timer(0)
|
||||
{
|
||||
for (auto client_filter = FilterNone; client_filter < _FilterCount; client_filter = eqFilterType(client_filter + 1)) {
|
||||
SetFilter(client_filter, FilterShow);
|
||||
@@ -446,7 +445,7 @@ Client::~Client() {
|
||||
m_tradeskill_object = nullptr;
|
||||
}
|
||||
|
||||
close_mobs.clear();
|
||||
m_close_mobs.clear();
|
||||
|
||||
if(IsDueling() && GetDuelTarget() != 0) {
|
||||
Entity* entity = entity_list.GetID(GetDuelTarget());
|
||||
@@ -7659,10 +7658,10 @@ void Client::SetFactionLevel(
|
||||
content_db.GetFactionData(&faction_modifiers, class_id, race_id, deity_id, e.faction_id);
|
||||
|
||||
if (is_quest) {
|
||||
if (e.npc_value > 0) {
|
||||
e.npc_value = -std::abs(e.npc_value);
|
||||
} else if (e.npc_value < 0) {
|
||||
e.npc_value = std::abs(e.npc_value);
|
||||
if (e.value > 0) {
|
||||
e.value = -std::abs(e.value);
|
||||
} else if (e.value < 0) {
|
||||
e.value = std::abs(e.value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9253,19 +9252,6 @@ bool Client::GotoPlayerRaid(const std::string& player_name)
|
||||
return true;
|
||||
}
|
||||
|
||||
glm::vec4 &Client::GetLastPositionBeforeBulkUpdate()
|
||||
{
|
||||
return last_position_before_bulk_update;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param in_last_position_before_bulk_update
|
||||
*/
|
||||
void Client::SetLastPositionBeforeBulkUpdate(glm::vec4 in_last_position_before_bulk_update)
|
||||
{
|
||||
Client::last_position_before_bulk_update = in_last_position_before_bulk_update;
|
||||
}
|
||||
|
||||
void Client::SendToGuildHall()
|
||||
{
|
||||
std::string zone_short_name = "guildhall";
|
||||
@@ -11117,7 +11103,8 @@ void Client::SaveDisciplines()
|
||||
CharacterDisciplinesRepository::DeleteWhere(
|
||||
database,
|
||||
fmt::format(
|
||||
"`slot_id` IN ({})",
|
||||
"`id` = {} AND `slot_id` IN ({})",
|
||||
CharacterID(),
|
||||
Strings::Join(delete_slots, ", ")
|
||||
)
|
||||
);
|
||||
@@ -12748,3 +12735,98 @@ void Client::SendTopLevelInventory()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// On a normal basis we limit mob movement updates based on distance
|
||||
// This ensures we send a periodic full zone update to a client that has started moving after 5 or so minutes
|
||||
//
|
||||
// For very large zones we will also force a full update based on distance
|
||||
//
|
||||
// We ignore a small distance around us so that we don't interrupt already pathing deltas as those npcs will appear
|
||||
// to full stop when they are actually still pathing
|
||||
void Client::CheckSendBulkClientPositionUpdate()
|
||||
{
|
||||
float distance_moved = DistanceNoZ(m_last_position_before_bulk_update, GetPosition());
|
||||
bool moved_far_enough_before_bulk_update = distance_moved >= zone->GetNpcPositionUpdateDistance();
|
||||
bool is_ready_to_update = (
|
||||
m_client_zone_wide_full_position_update_timer.Check() || moved_far_enough_before_bulk_update
|
||||
);
|
||||
|
||||
if (IsMoving() && is_ready_to_update) {
|
||||
LogDebug("[[{}]] Client Zone Wide Position Update NPCs", GetCleanName());
|
||||
|
||||
auto &mob_movement_manager = MobMovementManager::Get();
|
||||
auto &mob_list = entity_list.GetMobList();
|
||||
|
||||
for (auto &it : mob_list) {
|
||||
Mob *entity = it.second;
|
||||
if (!entity->IsNPC()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int animation_speed = 0;
|
||||
if (entity->IsMoving()) {
|
||||
if (entity->IsRunning()) {
|
||||
animation_speed = (entity->IsFeared() ? entity->GetFearSpeed() : entity->GetRunspeed());
|
||||
}
|
||||
else {
|
||||
animation_speed = entity->GetWalkspeed();
|
||||
}
|
||||
}
|
||||
|
||||
mob_movement_manager.SendCommandToClients(entity, 0.0, 0.0, 0.0, 0.0, animation_speed, ClientRangeAny, this);
|
||||
}
|
||||
|
||||
m_last_position_before_bulk_update = GetPosition();
|
||||
}
|
||||
}
|
||||
|
||||
const uint16 scan_npc_aggro_timer_idle = RuleI(Aggro, ClientAggroCheckIdleInterval);
|
||||
const uint16 scan_npc_aggro_timer_moving = RuleI(Aggro, ClientAggroCheckMovingInterval);
|
||||
|
||||
void Client::CheckClientToNpcAggroTimer()
|
||||
{
|
||||
LogAggroDetail(
|
||||
"ClientUpdate [{}] {}moving, scan timer [{}]",
|
||||
GetCleanName(),
|
||||
IsMoving() ? "" : "NOT ",
|
||||
m_client_npc_aggro_scan_timer.GetRemainingTime()
|
||||
);
|
||||
|
||||
if (IsMoving()) {
|
||||
if (m_client_npc_aggro_scan_timer.GetRemainingTime() > scan_npc_aggro_timer_moving) {
|
||||
LogAggroDetail("Client [{}] Restarting with moving timer", GetCleanName());
|
||||
m_client_npc_aggro_scan_timer.Disable();
|
||||
m_client_npc_aggro_scan_timer.Start(scan_npc_aggro_timer_moving);
|
||||
m_client_npc_aggro_scan_timer.Trigger();
|
||||
}
|
||||
}
|
||||
else if (m_client_npc_aggro_scan_timer.GetDuration() == scan_npc_aggro_timer_moving) {
|
||||
LogAggroDetail("Client [{}] Restarting with idle timer", GetCleanName());
|
||||
m_client_npc_aggro_scan_timer.Disable();
|
||||
m_client_npc_aggro_scan_timer.Start(scan_npc_aggro_timer_idle);
|
||||
}
|
||||
}
|
||||
|
||||
void Client::ClientToNpcAggroProcess()
|
||||
{
|
||||
if (zone->CanDoCombat() && !GetFeigned() && m_client_npc_aggro_scan_timer.Check()) {
|
||||
int npc_scan_count = 0;
|
||||
for (auto &close_mob: GetCloseMobList()) {
|
||||
Mob *mob = close_mob.second;
|
||||
if (!mob) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mob->IsClient()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mob->CheckWillAggro(this) && !mob->CheckAggro(this)) {
|
||||
mob->AddToHateList(this, 25);
|
||||
}
|
||||
|
||||
npc_scan_count++;
|
||||
}
|
||||
LogAggro("Checking Reverse Aggro (client->npc) scanned_npcs ([{}])", npc_scan_count);
|
||||
}
|
||||
}
|
||||
|
||||
+11
-8
@@ -1794,9 +1794,6 @@ public:
|
||||
|
||||
uint32 trapid; //ID of trap player has triggered. This is cleared when the player leaves the trap's radius, or it despawns.
|
||||
|
||||
void SetLastPositionBeforeBulkUpdate(glm::vec4 in_last_position_before_bulk_update);
|
||||
glm::vec4 &GetLastPositionBeforeBulkUpdate();
|
||||
|
||||
Raid *p_raid_instance;
|
||||
|
||||
void ShowDevToolsMenu();
|
||||
@@ -2033,8 +2030,6 @@ private:
|
||||
Timer fishing_timer;
|
||||
Timer endupkeep_timer;
|
||||
Timer autosave_timer;
|
||||
Timer client_scan_npc_aggro_timer;
|
||||
Timer client_zone_wide_full_position_update_timer;
|
||||
Timer tribute_timer;
|
||||
|
||||
Timer proximity_timer;
|
||||
@@ -2051,8 +2046,6 @@ private:
|
||||
Timer afk_toggle_timer;
|
||||
Timer helm_toggle_timer;
|
||||
Timer aggro_meter_timer;
|
||||
Timer mob_close_scan_timer;
|
||||
Timer position_update_timer; /* Timer used when client hasn't updated within a 10 second window */
|
||||
Timer consent_throttle_timer;
|
||||
Timer dynamiczone_removal_timer;
|
||||
Timer task_request_timer;
|
||||
@@ -2065,7 +2058,17 @@ private:
|
||||
int m_lazy_load_sent_bank_slots = 0;
|
||||
|
||||
glm::vec3 m_Proximity;
|
||||
glm::vec4 last_position_before_bulk_update;
|
||||
|
||||
// client aggro
|
||||
Timer m_client_npc_aggro_scan_timer;
|
||||
void CheckClientToNpcAggroTimer();
|
||||
void ClientToNpcAggroProcess();
|
||||
|
||||
// bulk position updates
|
||||
glm::vec4 m_last_position_before_bulk_update;
|
||||
Timer m_client_zone_wide_full_position_update_timer;
|
||||
Timer m_position_update_timer;
|
||||
void CheckSendBulkClientPositionUpdate();
|
||||
|
||||
void BulkSendInventoryItems();
|
||||
|
||||
|
||||
+5
-99
@@ -794,7 +794,7 @@ void Client::CompleteConnect()
|
||||
// sent to a succor point
|
||||
SendMobPositions();
|
||||
|
||||
SetLastPositionBeforeBulkUpdate(GetPosition());
|
||||
m_last_position_before_bulk_update = GetPosition();
|
||||
|
||||
/* This sub event is for if a player logs in for the first time since entering world. */
|
||||
if (firstlogon == 1) {
|
||||
@@ -940,7 +940,7 @@ void Client::CompleteConnect()
|
||||
|
||||
worldserver.RequestTellQueue(GetName());
|
||||
|
||||
entity_list.ScanCloseMobs(close_mobs, this, true);
|
||||
entity_list.ScanCloseMobs(this);
|
||||
|
||||
if (GetGM() && IsDevToolsEnabled()) {
|
||||
ShowDevToolsMenu();
|
||||
@@ -5012,103 +5012,9 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) {
|
||||
|
||||
SetMoving(!(cy == m_Position.y && cx == m_Position.x));
|
||||
|
||||
/**
|
||||
* Client aggro scanning
|
||||
*/
|
||||
const uint16 client_scan_npc_aggro_timer_idle = RuleI(Aggro, ClientAggroCheckIdleInterval);
|
||||
const uint16 client_scan_npc_aggro_timer_moving = RuleI(Aggro, ClientAggroCheckMovingInterval);
|
||||
|
||||
LogAggroDetail(
|
||||
"ClientUpdate [{}] {}moving, scan timer [{}]",
|
||||
GetCleanName(),
|
||||
IsMoving() ? "" : "NOT ",
|
||||
client_scan_npc_aggro_timer.GetRemainingTime()
|
||||
);
|
||||
|
||||
if (IsMoving()) {
|
||||
if (client_scan_npc_aggro_timer.GetRemainingTime() > client_scan_npc_aggro_timer_moving) {
|
||||
LogAggroDetail("Client [{}] Restarting with moving timer", GetCleanName());
|
||||
client_scan_npc_aggro_timer.Disable();
|
||||
client_scan_npc_aggro_timer.Start(client_scan_npc_aggro_timer_moving);
|
||||
client_scan_npc_aggro_timer.Trigger();
|
||||
}
|
||||
}
|
||||
else if (client_scan_npc_aggro_timer.GetDuration() == client_scan_npc_aggro_timer_moving) {
|
||||
LogAggroDetail("Client [{}] Restarting with idle timer", GetCleanName());
|
||||
client_scan_npc_aggro_timer.Disable();
|
||||
client_scan_npc_aggro_timer.Start(client_scan_npc_aggro_timer_idle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Client mob close list cache scan timer
|
||||
*/
|
||||
const uint16 client_mob_close_scan_timer_moving = 6000;
|
||||
const uint16 client_mob_close_scan_timer_idle = 60000;
|
||||
|
||||
LogAIScanCloseDetail(
|
||||
"Client [{}] {}moving, scan timer [{}]",
|
||||
GetCleanName(),
|
||||
IsMoving() ? "" : "NOT ",
|
||||
mob_close_scan_timer.GetRemainingTime()
|
||||
);
|
||||
|
||||
if (IsMoving()) {
|
||||
if (mob_close_scan_timer.GetRemainingTime() > client_mob_close_scan_timer_moving) {
|
||||
LogAIScanCloseDetail("Client [{}] Restarting with moving timer", GetCleanName());
|
||||
mob_close_scan_timer.Disable();
|
||||
mob_close_scan_timer.Start(client_mob_close_scan_timer_moving);
|
||||
mob_close_scan_timer.Trigger();
|
||||
}
|
||||
}
|
||||
else if (mob_close_scan_timer.GetDuration() == client_mob_close_scan_timer_moving) {
|
||||
LogAIScanCloseDetail("Client [{}] Restarting with idle timer", GetCleanName());
|
||||
mob_close_scan_timer.Disable();
|
||||
mob_close_scan_timer.Start(client_mob_close_scan_timer_idle);
|
||||
}
|
||||
|
||||
/**
|
||||
* On a normal basis we limit mob movement updates based on distance
|
||||
* This ensures we send a periodic full zone update to a client that has started moving after 5 or so minutes
|
||||
*
|
||||
* For very large zones we will also force a full update based on distance
|
||||
*
|
||||
* We ignore a small distance around us so that we don't interrupt already pathing deltas as those npcs will appear
|
||||
* to full stop when they are actually still pathing
|
||||
*/
|
||||
|
||||
float distance_moved = DistanceNoZ(GetLastPositionBeforeBulkUpdate(), GetPosition());
|
||||
bool moved_far_enough_before_bulk_update = distance_moved >= zone->GetNpcPositionUpdateDistance();
|
||||
bool is_ready_to_update = (
|
||||
client_zone_wide_full_position_update_timer.Check() || moved_far_enough_before_bulk_update
|
||||
);
|
||||
|
||||
if (IsMoving() && is_ready_to_update) {
|
||||
LogDebug("[[{}]] Client Zone Wide Position Update NPCs", GetCleanName());
|
||||
|
||||
auto &mob_movement_manager = MobMovementManager::Get();
|
||||
auto &mob_list = entity_list.GetMobList();
|
||||
|
||||
for (auto &it : mob_list) {
|
||||
Mob *entity = it.second;
|
||||
if (!entity->IsNPC()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int animation_speed = 0;
|
||||
if (entity->IsMoving()) {
|
||||
if (entity->IsRunning()) {
|
||||
animation_speed = (entity->IsFeared() ? entity->GetFearSpeed() : entity->GetRunspeed());
|
||||
}
|
||||
else {
|
||||
animation_speed = entity->GetWalkspeed();
|
||||
}
|
||||
}
|
||||
|
||||
mob_movement_manager.SendCommandToClients(entity, 0.0, 0.0, 0.0, 0.0, animation_speed, ClientRangeAny, this);
|
||||
}
|
||||
|
||||
SetLastPositionBeforeBulkUpdate(GetPosition());
|
||||
}
|
||||
CheckClientToNpcAggroTimer();
|
||||
CheckScanCloseMobsMovingTimer();
|
||||
CheckSendBulkClientPositionUpdate();
|
||||
|
||||
int32 new_animation = ppu->animation;
|
||||
|
||||
|
||||
+3
-32
@@ -121,7 +121,7 @@ bool Client::Process() {
|
||||
}
|
||||
|
||||
/* I haven't naturally updated my position in 10 seconds, updating manually */
|
||||
if (!IsMoving() && position_update_timer.Check()) {
|
||||
if (!IsMoving() && m_position_update_timer.Check()) {
|
||||
SentPositionPacket(0.0f, 0.0f, 0.0f, 0.0f, 0);
|
||||
}
|
||||
|
||||
@@ -281,13 +281,7 @@ bool Client::Process() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scan close range mobs
|
||||
* Used in aggro checks
|
||||
*/
|
||||
if (mob_close_scan_timer.Check()) {
|
||||
entity_list.ScanCloseMobs(close_mobs, this, IsMoving());
|
||||
}
|
||||
ScanCloseMobProcess();
|
||||
|
||||
if (RuleB(Inventory, LazyLoadBank)) {
|
||||
// poll once a second to see if we are close to a banker and we haven't loaded the bank yet
|
||||
@@ -608,30 +602,7 @@ bool Client::Process() {
|
||||
}
|
||||
}
|
||||
|
||||
//At this point, we are still connected, everything important has taken
|
||||
//place, now check to see if anybody wants to aggro us.
|
||||
// only if client is not feigned
|
||||
if (zone->CanDoCombat() && ret && !GetFeigned() && client_scan_npc_aggro_timer.Check()) {
|
||||
int npc_scan_count = 0;
|
||||
for (auto & close_mob : close_mobs) {
|
||||
Mob *mob = close_mob.second;
|
||||
|
||||
if (!mob) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mob->IsClient()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mob->CheckWillAggro(this) && !mob->CheckAggro(this)) {
|
||||
mob->AddToHateList(this, 25);
|
||||
}
|
||||
|
||||
npc_scan_count++;
|
||||
}
|
||||
LogAggro("Checking Reverse Aggro (client->npc) scanned_npcs ([{}])", npc_scan_count);
|
||||
}
|
||||
ClientToNpcAggroProcess();
|
||||
|
||||
if (client_state != CLIENT_LINKDEAD && (client_state == CLIENT_ERROR || client_state == DISCONNECTED || client_state == CLIENT_KICKED || !eqs->CheckState(ESTABLISHED)))
|
||||
{
|
||||
|
||||
+4
-4
@@ -1036,7 +1036,7 @@ void EntityList::AETaunt(Client* taunter, float range, int bonus_hate)
|
||||
|
||||
float range_squared = range * range;
|
||||
|
||||
for (auto& it: entity_list.GetCloseMobList(taunter, range)) {
|
||||
for (auto& it: taunter->GetCloseMobList(range)) {
|
||||
Mob *them = it.second;
|
||||
if (!them) {
|
||||
continue;
|
||||
@@ -1120,7 +1120,7 @@ void EntityList::AESpell(
|
||||
distance
|
||||
);
|
||||
|
||||
for (auto& it: entity_list.GetCloseMobList(caster_mob, distance)) {
|
||||
for (auto& it: caster_mob->GetCloseMobList(distance)) {
|
||||
current_mob = it.second;
|
||||
if (!current_mob) {
|
||||
continue;
|
||||
@@ -1256,7 +1256,7 @@ void EntityList::MassGroupBuff(
|
||||
float distance_squared = distance * distance;
|
||||
bool is_detrimental_spell = IsDetrimentalSpell(spell_id);
|
||||
|
||||
for (auto& it: entity_list.GetCloseMobList(caster, distance)) {
|
||||
for (auto& it: caster->GetCloseMobList(distance)) {
|
||||
current_mob = it.second;
|
||||
if (!current_mob) {
|
||||
continue;
|
||||
@@ -1306,7 +1306,7 @@ void EntityList::AEAttack(
|
||||
float distance_squared = distance * distance;
|
||||
int current_hits = 0;
|
||||
|
||||
for (auto& it: entity_list.GetCloseMobList(attacker, distance)) {
|
||||
for (auto& it: attacker->GetCloseMobList(distance)) {
|
||||
current_mob = it.second;
|
||||
if (!current_mob) {
|
||||
continue;
|
||||
|
||||
+43
-52
@@ -696,7 +696,7 @@ void EntityList::AddNPC(NPC *npc, bool send_spawn_packet, bool dont_queue)
|
||||
npc_list.emplace(std::pair<uint16, NPC *>(npc->GetID(), npc));
|
||||
mob_list.emplace(std::pair<uint16, Mob *>(npc->GetID(), npc));
|
||||
|
||||
entity_list.ScanCloseMobs(npc->close_mobs, npc, true);
|
||||
entity_list.ScanCloseMobs(npc);
|
||||
|
||||
if (parse->HasQuestSub(npc->GetNPCTypeID(), EVENT_SPAWN)) {
|
||||
parse->EventNPC(EVENT_SPAWN, npc, nullptr, "", 0);
|
||||
@@ -1742,8 +1742,7 @@ void EntityList::QueueCloseClients(
|
||||
}
|
||||
|
||||
float distance_squared = distance * distance;
|
||||
|
||||
for (auto &e : GetCloseMobList(sender, distance)) {
|
||||
for (auto &e : sender->GetCloseMobList(distance)) {
|
||||
Mob *mob = e.second;
|
||||
if (!mob) {
|
||||
continue;
|
||||
@@ -2886,7 +2885,7 @@ bool EntityList::RemoveMobFromCloseLists(Mob *mob)
|
||||
entity_id
|
||||
);
|
||||
|
||||
it->second->close_mobs.erase(entity_id);
|
||||
it->second->m_close_mobs.erase(entity_id);
|
||||
++it;
|
||||
}
|
||||
|
||||
@@ -2911,49 +2910,40 @@ void EntityList::RemoveAuraFromMobs(Mob *aura)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The purpose of this system is so that we cache relevant entities that are "close"
|
||||
*
|
||||
* In general; it becomes incredibly expensive to run zone-wide checks against every single mob in the zone when in reality
|
||||
* we only care about entities closest to us
|
||||
*
|
||||
* A very simple example of where this is relevant is Aggro, the below example is skewed because the overall implementation
|
||||
* of Aggro was also tweaked in conjunction with close lists. We also scan more aggressively when entities are moving (1-6 seconds)
|
||||
* versus 60 seconds when idle. We also have entities that are moving add themselves to those closest to them so that their close
|
||||
* lists remain always up to date
|
||||
*
|
||||
* Before: Aggro checks for NPC to Client aggro | (40 clients in zone) x (525 npcs) x 2 (times a second) = 2,520,000 checks a minute
|
||||
* After: Aggro checks for NPC to Client aggro | (40 clients in zone) x (20-30 npcs) x 2 (times a second) = 144,000 checks a minute (This is actually far less today)
|
||||
*
|
||||
* Places in the code where this logic makes a huge impact
|
||||
*
|
||||
* Aggro checks (zone wide -> close)
|
||||
* Aura processing (zone wide -> close)
|
||||
* AE Taunt (zone wide -> close)
|
||||
* AOE Spells (zone wide -> close)
|
||||
* Bard Pulse AOE (zone wide -> close)
|
||||
* Mass Group Buff (zone wide -> close)
|
||||
* AE Attack (zone wide -> close)
|
||||
* Packet QueueCloseClients (zone wide -> close)
|
||||
* Check Close Beneficial Spells (Buffs; should I heal other npcs) (zone wide -> close)
|
||||
* AI Yell for Help (NPC Assist other NPCs) (zone wide -> close)
|
||||
*
|
||||
* All of the above makes a tremendous impact on the bottom line of cpu cycle performance because we run an order of magnitude
|
||||
* less checks by focusing our hot path logic down to a very small subset of relevant entities instead of looping an entire
|
||||
* entity list (zone wide)
|
||||
*
|
||||
* @param close_mobs
|
||||
* @param scanning_mob
|
||||
*/
|
||||
void EntityList::ScanCloseMobs(
|
||||
std::unordered_map<uint16, Mob *> &close_mobs,
|
||||
Mob *scanning_mob,
|
||||
bool add_self_to_other_lists
|
||||
)
|
||||
// The purpose of this system is so that we cache relevant entities that are "close"
|
||||
//
|
||||
// In general; it becomes incredibly expensive to run zone-wide checks against every single mob in the zone when in reality
|
||||
// we only care about entities closest to us
|
||||
//
|
||||
// A very simple example of where this is relevant is Aggro, the below example is skewed because the overall implementation
|
||||
// of Aggro was also tweaked in conjunction with close lists. We also scan more aggressively when entities are moving (1-6 seconds)
|
||||
// versus 60 seconds when idle. We also have entities that are moving add themselves to those closest to them so that their close
|
||||
// lists remain always up to date
|
||||
//
|
||||
// Before: Aggro checks for NPC to Client aggro | (40 clients in zone) x (525 npcs) x 2 (times a second) = 2,520,000 checks a minute
|
||||
// After: Aggro checks for NPC to Client aggro | (40 clients in zone) x (20-30 npcs) x 2 (times a second) = 144,000 checks a minute (This is // tually far less today)
|
||||
//
|
||||
// Places in the code where this logic makes a huge impact
|
||||
//
|
||||
// Aggro checks (zone wide -> close)
|
||||
// Aura processing (zone wide -> close)
|
||||
// AE Taunt (zone wide -> close)
|
||||
// AOE Spells (zone wide -> close)
|
||||
// Bard Pulse AOE (zone wide -> close)
|
||||
// Mass Group Buff (zone wide -> close)
|
||||
// AE Attack (zone wide -> close)
|
||||
// Packet QueueCloseClients (zone wide -> close)
|
||||
// Check Close Beneficial Spells (Buffs; should I heal other npcs) (zone wide -> close)
|
||||
// AI Yell for Help (NPC Assist other NPCs) (zone wide -> close)
|
||||
//
|
||||
// All of the above makes a tremendous impact on the bottom line of cpu cycle performance because we run an order of magnitude
|
||||
// less checks by focusing our hot path logic down to a very small subset of relevant entities instead of looping an entire
|
||||
// entity list (zone wide)
|
||||
void EntityList::ScanCloseMobs(Mob *scanning_mob)
|
||||
{
|
||||
float scan_range = RuleI(Range, MobCloseScanDistance) * RuleI(Range, MobCloseScanDistance);
|
||||
|
||||
close_mobs.clear();
|
||||
scanning_mob->m_close_mobs.clear();
|
||||
|
||||
for (auto &e : mob_list) {
|
||||
auto mob = e.second;
|
||||
@@ -2963,12 +2953,13 @@ void EntityList::ScanCloseMobs(
|
||||
|
||||
float distance = DistanceSquared(scanning_mob->GetPosition(), mob->GetPosition());
|
||||
if (distance <= scan_range || mob->GetAggroRange() >= scan_range) {
|
||||
close_mobs.emplace(std::pair<uint16, Mob *>(mob->GetID(), mob));
|
||||
scanning_mob->m_close_mobs.emplace(std::pair<uint16, Mob *>(mob->GetID(), mob));
|
||||
|
||||
if (add_self_to_other_lists && scanning_mob->GetID() > 0) {
|
||||
// add self to other mobs close list
|
||||
if (scanning_mob->GetID() > 0) {
|
||||
bool has_mob = false;
|
||||
|
||||
for (auto &cm: mob->close_mobs) {
|
||||
for (auto &cm: mob->m_close_mobs) {
|
||||
if (scanning_mob->GetID() == cm.first) {
|
||||
has_mob = true;
|
||||
break;
|
||||
@@ -2976,7 +2967,7 @@ void EntityList::ScanCloseMobs(
|
||||
}
|
||||
|
||||
if (!has_mob) {
|
||||
mob->close_mobs.insert(std::pair<uint16, Mob *>(scanning_mob->GetID(), scanning_mob));
|
||||
mob->m_close_mobs.insert(std::pair<uint16, Mob *>(scanning_mob->GetID(), scanning_mob));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2985,7 +2976,7 @@ void EntityList::ScanCloseMobs(
|
||||
LogAIScanCloseDetail(
|
||||
"[{}] Scanning Close List | list_size [{}] moving [{}]",
|
||||
scanning_mob->GetCleanName(),
|
||||
close_mobs.size(),
|
||||
scanning_mob->m_close_mobs.size(),
|
||||
scanning_mob->IsMoving() ? "true" : "false"
|
||||
);
|
||||
}
|
||||
@@ -4448,7 +4439,7 @@ void EntityList::QuestJournalledSayClose(
|
||||
buf.WriteInt32(0);
|
||||
|
||||
if (RuleB(Chat, QuestDialogueUsesDialogueWindow)) {
|
||||
for (auto &e : GetCloseMobList(sender, (dist * dist))) {
|
||||
for (auto &e : sender->GetCloseMobList(dist)) {
|
||||
Mob *mob = e.second;
|
||||
if (!mob) {
|
||||
continue;
|
||||
@@ -5651,7 +5642,7 @@ std::vector<Mob*> EntityList::GetTargetsForVirusEffect(Mob *spreader, Mob *origi
|
||||
|
||||
std::vector<Mob *> spreader_list = {};
|
||||
bool is_detrimental_spell = IsDetrimentalSpell(spell_id);
|
||||
for (auto &it : entity_list.GetCloseMobList(spreader, range)) {
|
||||
for (auto &it : spreader->GetCloseMobList(range)) {
|
||||
Mob *mob = it.second;
|
||||
if (!mob) {
|
||||
continue;
|
||||
@@ -5781,7 +5772,7 @@ void EntityList::ReloadMerchants() {
|
||||
std::unordered_map<uint16, Mob *> &EntityList::GetCloseMobList(Mob *mob, float distance)
|
||||
{
|
||||
if (distance <= RuleI(Range, MobCloseScanDistance)) {
|
||||
return mob->close_mobs;
|
||||
return mob->m_close_mobs;
|
||||
}
|
||||
|
||||
return mob_list;
|
||||
|
||||
+1
-5
@@ -566,11 +566,7 @@ public:
|
||||
void RefreshAutoXTargets(Client *c);
|
||||
void RefreshClientXTargets(Client *c);
|
||||
void SendAlternateAdvancementStats();
|
||||
void ScanCloseMobs(
|
||||
std::unordered_map<uint16, Mob *> &close_mobs,
|
||||
Mob *scanning_mob,
|
||||
bool add_self_to_other_lists = false
|
||||
);
|
||||
void ScanCloseMobs(Mob *scanning_mob);
|
||||
|
||||
void GetTrapInfo(Client* c);
|
||||
bool IsTrapGroupSpawned(uint32 trap_id, uint8 group);
|
||||
|
||||
+78
-12
@@ -128,8 +128,9 @@ Mob::Mob(
|
||||
attack_anim_timer(500),
|
||||
position_update_melee_push_timer(500),
|
||||
hate_list_cleanup_timer(6000),
|
||||
mob_close_scan_timer(6000),
|
||||
mob_check_moving_timer(1000)
|
||||
m_scan_close_mobs_timer(6000),
|
||||
m_mob_check_moving_timer(1000),
|
||||
bot_attack_flag_timer(10000)
|
||||
{
|
||||
mMovementManager = &MobMovementManager::Get();
|
||||
mMovementManager->AddMob(this);
|
||||
@@ -400,6 +401,10 @@ Mob::Mob(
|
||||
pet_owner_npc = false;
|
||||
pet_targetlock_id = 0;
|
||||
|
||||
//bot attack flag
|
||||
bot_attack_flags.clear();
|
||||
bot_attack_flag_timer.Disable();
|
||||
|
||||
attacked_count = 0;
|
||||
mezzed = false;
|
||||
stunned = false;
|
||||
@@ -512,7 +517,7 @@ Mob::Mob(
|
||||
|
||||
m_manual_follow = false;
|
||||
|
||||
mob_close_scan_timer.Trigger();
|
||||
m_scan_close_mobs_timer.Trigger();
|
||||
|
||||
SetCanOpenDoors(true);
|
||||
|
||||
@@ -565,7 +570,7 @@ Mob::~Mob()
|
||||
entity_list.RemoveMobFromCloseLists(this);
|
||||
entity_list.RemoveAuraFromMobs(this);
|
||||
|
||||
close_mobs.clear();
|
||||
m_close_mobs.clear();
|
||||
|
||||
LeaveHealRotationTargetPool();
|
||||
}
|
||||
@@ -5012,7 +5017,7 @@ void Mob::Say(const char *format, ...)
|
||||
int16 distance = 200;
|
||||
|
||||
if (RuleB(Chat, QuestDialogueUsesDialogueWindow)) {
|
||||
for (auto &e : entity_list.GetCloseMobList(talker, (distance * distance))) {
|
||||
for (auto &e : talker->GetCloseMobList(distance)) {
|
||||
Mob *mob = e.second;
|
||||
if (!mob) {
|
||||
continue;
|
||||
@@ -6171,9 +6176,7 @@ int32 Mob::GetPositionalDmgTakenAmt(Mob *attacker)
|
||||
|
||||
void Mob::SetBottomRampageList()
|
||||
{
|
||||
auto &mob_list = entity_list.GetCloseMobList(this);
|
||||
|
||||
for (auto &e : mob_list) {
|
||||
for (auto &e : GetCloseMobList()) {
|
||||
auto mob = e.second;
|
||||
if (!mob) {
|
||||
continue;
|
||||
@@ -6198,9 +6201,7 @@ void Mob::SetBottomRampageList()
|
||||
|
||||
void Mob::SetTopRampageList()
|
||||
{
|
||||
auto &mob_list = entity_list.GetCloseMobList(this);
|
||||
|
||||
for (auto &e : mob_list) {
|
||||
for (auto &e : GetCloseMobList()) {
|
||||
auto mob = e.second;
|
||||
if (!mob) {
|
||||
continue;
|
||||
@@ -8614,7 +8615,7 @@ void Mob::SetExtraHaste(int haste, bool need_to_save)
|
||||
|
||||
bool Mob::IsCloseToBanker()
|
||||
{
|
||||
for (auto &e: entity_list.GetCloseMobList(this)) {
|
||||
for (auto &e: GetCloseMobList()) {
|
||||
auto mob = e.second;
|
||||
if (mob && mob->IsNPC() && mob->GetClass() == Class::Banker) {
|
||||
return true;
|
||||
@@ -8623,3 +8624,68 @@ bool Mob::IsCloseToBanker()
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Mob::HasBotAttackFlag(Mob* tar) {
|
||||
if (!tar) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<uint32> l = tar->GetBotAttackFlags();
|
||||
|
||||
for (uint32 e : l) {
|
||||
if (IsBot() && e == CastToBot()->GetBotOwnerCharacterID()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (IsClient() && e == CastToClient()->CharacterID()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
const uint16 scan_close_mobs_timer_moving = 6000; // 6 seconds
|
||||
const uint16 scan_close_mobs_timer_idle = 60000; // 60 seconds
|
||||
|
||||
void Mob::CheckScanCloseMobsMovingTimer()
|
||||
{
|
||||
LogAIScanCloseDetail(
|
||||
"Mob [{}] {}moving, scan timer [{}]",
|
||||
GetCleanName(),
|
||||
IsMoving() ? "" : "NOT ",
|
||||
m_scan_close_mobs_timer.GetRemainingTime()
|
||||
);
|
||||
|
||||
// If the moving timer triggers, lets see if we are moving or idle to restart the appropriate
|
||||
// dynamic timer
|
||||
if (m_mob_check_moving_timer.Check()) {
|
||||
// If the mob is still moving, restart the moving timer
|
||||
if (moving) {
|
||||
if (m_scan_close_mobs_timer.GetRemainingTime() > scan_close_mobs_timer_moving) {
|
||||
LogAIScanCloseDetail("Mob [{}] Restarting with moving timer", GetCleanName());
|
||||
m_scan_close_mobs_timer.Disable();
|
||||
m_scan_close_mobs_timer.Start(scan_close_mobs_timer_moving);
|
||||
m_scan_close_mobs_timer.Trigger();
|
||||
}
|
||||
}
|
||||
// If the mob is not moving, restart the idle timer
|
||||
else if (m_scan_close_mobs_timer.GetDuration() == scan_close_mobs_timer_moving) {
|
||||
LogAIScanCloseDetail("Mob [{}] Restarting with idle timer", GetCleanName());
|
||||
m_scan_close_mobs_timer.Disable();
|
||||
m_scan_close_mobs_timer.Start(scan_close_mobs_timer_idle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Mob::ScanCloseMobProcess()
|
||||
{
|
||||
if (m_scan_close_mobs_timer.Check()) {
|
||||
entity_list.ScanCloseMobs(this);
|
||||
}
|
||||
}
|
||||
|
||||
std::unordered_map<uint16, Mob *> &Mob::GetCloseMobList(float distance)
|
||||
{
|
||||
return entity_list.GetCloseMobList(this, distance);
|
||||
}
|
||||
|
||||
+18
-3
@@ -201,9 +201,12 @@ public:
|
||||
|
||||
void DisplayInfo(Mob *mob);
|
||||
|
||||
std::unordered_map<uint16, Mob *> close_mobs;
|
||||
Timer mob_close_scan_timer;
|
||||
Timer mob_check_moving_timer;
|
||||
std::unordered_map<uint16, Mob *> m_close_mobs;
|
||||
Timer m_scan_close_mobs_timer;
|
||||
Timer m_mob_check_moving_timer;
|
||||
|
||||
// Bot attack flag
|
||||
Timer bot_attack_flag_timer;
|
||||
|
||||
//Somewhat sorted: needs documenting!
|
||||
|
||||
@@ -1102,6 +1105,11 @@ public:
|
||||
bool invulnerable;
|
||||
bool qglobal;
|
||||
|
||||
inline std::vector<uint32> GetBotAttackFlags() { return bot_attack_flags; }
|
||||
inline void SetBotAttackFlag(uint32 value) { bot_attack_flags.push_back(value); }
|
||||
inline void ClearBotAttackFlags() { bot_attack_flags.clear(); }
|
||||
bool HasBotAttackFlag(Mob* tar);
|
||||
|
||||
virtual void SetAttackTimer();
|
||||
inline void SetInvul(bool invul) { invulnerable=invul; }
|
||||
inline bool GetInvul(void) { return invulnerable; }
|
||||
@@ -1479,6 +1487,10 @@ public:
|
||||
|
||||
bool IsCloseToBanker();
|
||||
|
||||
void ScanCloseMobProcess();
|
||||
std::unordered_map<uint16, Mob *> &GetCloseMobList(float distance = 0.0f);
|
||||
void CheckScanCloseMobsMovingTimer();
|
||||
|
||||
protected:
|
||||
void CommonDamage(Mob* other, int64 &damage, const uint16 spell_id, const EQ::skills::SkillType attack_skill, bool &avoidable, const int8 buffslot, const bool iBuffTic, eSpecialAttacks specal = eSpecialAttacks::None);
|
||||
static uint16 GetProcID(uint16 spell_id, uint8 effect_index);
|
||||
@@ -1863,6 +1875,9 @@ protected:
|
||||
bool pet_owner_npc; // Flags pets as belonging to an NPC
|
||||
uint32 pet_targetlock_id;
|
||||
|
||||
//bot attack flags
|
||||
std::vector<uint32> bot_attack_flags;
|
||||
|
||||
glm::vec3 m_TargetRing;
|
||||
|
||||
GravityBehavior flymode;
|
||||
|
||||
+2
-23
@@ -1391,29 +1391,8 @@ void Mob::AI_Process() {
|
||||
StopNavigation();
|
||||
}
|
||||
}
|
||||
else if (zone->CanDoCombat() && CastToNPC()->GetNPCAggro() && AI_scan_area_timer->Check()) {
|
||||
|
||||
/**
|
||||
* NPC to NPC aggro (npc_aggro flag set)
|
||||
*/
|
||||
for (auto &close_mob : close_mobs) {
|
||||
Mob *mob = close_mob.second;
|
||||
|
||||
if (mob->IsClient()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (CheckWillAggro(mob)) {
|
||||
AddToHateList(mob);
|
||||
}
|
||||
}
|
||||
|
||||
AI_scan_area_timer->Disable();
|
||||
AI_scan_area_timer->Start(
|
||||
RandomTimer(RuleI(NPC, NPCToNPCAggroTimerMin), RuleI(NPC, NPCToNPCAggroTimerMax)),
|
||||
false
|
||||
);
|
||||
|
||||
else if (zone->CanDoCombat() && IsNPC() && CastToNPC()->GetNPCAggro() && AI_scan_area_timer->Check()) {
|
||||
CastToNPC()->DoNpcToNpcAggroScan();
|
||||
}
|
||||
else if (AI_movement_timer->Check() && !IsRooted()) {
|
||||
if (IsPet()) {
|
||||
|
||||
@@ -127,11 +127,6 @@ public:
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mob_movement_manager
|
||||
* @param mob
|
||||
* @return
|
||||
*/
|
||||
virtual bool Process(MobMovementManager *mob_movement_manager, Mob *mob)
|
||||
{
|
||||
if (!mob->IsAIControlled()) {
|
||||
@@ -286,11 +281,6 @@ public:
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mob_movement_manager
|
||||
* @param mob
|
||||
* @return
|
||||
*/
|
||||
virtual bool Process(MobMovementManager *mob_movement_manager, Mob *mob)
|
||||
{
|
||||
if (!mob->IsAIControlled()) {
|
||||
@@ -707,33 +697,21 @@ void MobMovementManager::Process()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mob
|
||||
*/
|
||||
void MobMovementManager::AddMob(Mob *mob)
|
||||
{
|
||||
_impl->Entries.insert(std::make_pair(mob, MobMovementEntry()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mob
|
||||
*/
|
||||
void MobMovementManager::RemoveMob(Mob *mob)
|
||||
{
|
||||
_impl->Entries.erase(mob);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param client
|
||||
*/
|
||||
void MobMovementManager::AddClient(Client *client)
|
||||
{
|
||||
_impl->Clients.push_back(client);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param client
|
||||
*/
|
||||
void MobMovementManager::RemoveClient(Client *client)
|
||||
{
|
||||
auto iter = _impl->Clients.begin();
|
||||
@@ -747,11 +725,6 @@ void MobMovementManager::RemoveClient(Client *client)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param who
|
||||
* @param to
|
||||
* @param mob_movement_mode
|
||||
*/
|
||||
void MobMovementManager::RotateTo(Mob *who, float to, MobMovementMode mob_movement_mode)
|
||||
{
|
||||
auto iter = _impl->Entries.find(who);
|
||||
@@ -764,13 +737,6 @@ void MobMovementManager::RotateTo(Mob *who, float to, MobMovementMode mob_moveme
|
||||
PushRotateTo(ent.second, who, to, mob_movement_mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param who
|
||||
* @param x
|
||||
* @param y
|
||||
* @param z
|
||||
* @param heading
|
||||
*/
|
||||
void MobMovementManager::Teleport(Mob *who, float x, float y, float z, float heading)
|
||||
{
|
||||
auto iter = _impl->Entries.find(who);
|
||||
@@ -781,13 +747,6 @@ void MobMovementManager::Teleport(Mob *who, float x, float y, float z, float hea
|
||||
PushTeleportTo(ent.second, x, y, z, heading);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param who
|
||||
* @param x
|
||||
* @param y
|
||||
* @param z
|
||||
* @param mode
|
||||
*/
|
||||
void MobMovementManager::NavigateTo(Mob *who, float x, float y, float z, MobMovementMode mode)
|
||||
{
|
||||
if (IsPositionEqualWithinCertainZ(glm::vec3(x, y, z), glm::vec3(who->GetX(), who->GetY(), who->GetZ()), 6.0f)) {
|
||||
@@ -824,9 +783,6 @@ void MobMovementManager::NavigateTo(Mob *who, float x, float y, float z, MobMove
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param who
|
||||
*/
|
||||
void MobMovementManager::StopNavigation(Mob *who)
|
||||
{
|
||||
auto iter = _impl->Entries.find(who);
|
||||
@@ -852,16 +808,6 @@ void MobMovementManager::StopNavigation(Mob *who)
|
||||
PushStopMoving(ent.second);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mob
|
||||
* @param delta_x
|
||||
* @param delta_y
|
||||
* @param delta_z
|
||||
* @param delta_heading
|
||||
* @param anim
|
||||
* @param range
|
||||
* @param single_client
|
||||
*/
|
||||
void MobMovementManager::SendCommandToClients(
|
||||
Mob *mob,
|
||||
float delta_x,
|
||||
@@ -961,10 +907,6 @@ void MobMovementManager::SendCommandToClients(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param in
|
||||
* @return
|
||||
*/
|
||||
float MobMovementManager::FixHeading(float in)
|
||||
{
|
||||
auto h = in;
|
||||
@@ -979,9 +921,6 @@ float MobMovementManager::FixHeading(float in)
|
||||
return h;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param client
|
||||
*/
|
||||
void MobMovementManager::DumpStats(Client *client)
|
||||
{
|
||||
auto current_time = static_cast<double>(Timer::GetCurrentTime()) / 1000.0;
|
||||
@@ -1062,13 +1001,6 @@ void MobMovementManager::FillCommandStruct(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param who
|
||||
* @param x
|
||||
* @param y
|
||||
* @param z
|
||||
* @param mob_movement_mode
|
||||
*/
|
||||
void MobMovementManager::UpdatePath(Mob *who, float x, float y, float z, MobMovementMode mob_movement_mode)
|
||||
{
|
||||
Mob *target=who->GetTarget();
|
||||
@@ -1114,13 +1046,6 @@ void MobMovementManager::UpdatePath(Mob *who, float x, float y, float z, MobMove
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param who
|
||||
* @param x
|
||||
* @param y
|
||||
* @param z
|
||||
* @param mode
|
||||
*/
|
||||
void MobMovementManager::UpdatePathGround(Mob *who, float x, float y, float z, MobMovementMode mode)
|
||||
{
|
||||
PathfinderOptions opts;
|
||||
@@ -1253,13 +1178,6 @@ void MobMovementManager::UpdatePathGround(Mob *who, float x, float y, float z, M
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param who
|
||||
* @param x
|
||||
* @param y
|
||||
* @param z
|
||||
* @param movement_mode
|
||||
*/
|
||||
void MobMovementManager::UpdatePathUnderwater(Mob *who, float x, float y, float z, MobMovementMode movement_mode)
|
||||
{
|
||||
auto eiter = _impl->Entries.find(who);
|
||||
@@ -1368,13 +1286,6 @@ void MobMovementManager::UpdatePathUnderwater(Mob *who, float x, float y, float
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param who
|
||||
* @param x
|
||||
* @param y
|
||||
* @param z
|
||||
* @param mode
|
||||
*/
|
||||
void MobMovementManager::UpdatePathBoat(Mob *who, float x, float y, float z, MobMovementMode mode)
|
||||
{
|
||||
auto eiter = _impl->Entries.find(who);
|
||||
@@ -1386,48 +1297,21 @@ void MobMovementManager::UpdatePathBoat(Mob *who, float x, float y, float z, Mob
|
||||
PushStopMoving(ent.second);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ent
|
||||
* @param x
|
||||
* @param y
|
||||
* @param z
|
||||
* @param heading
|
||||
*/
|
||||
void MobMovementManager::PushTeleportTo(MobMovementEntry &ent, float x, float y, float z, float heading)
|
||||
{
|
||||
ent.Commands.emplace_back(std::unique_ptr<IMovementCommand>(new TeleportToCommand(x, y, z, heading)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ent
|
||||
* @param x
|
||||
* @param y
|
||||
* @param z
|
||||
* @param mob_movement_mode
|
||||
*/
|
||||
void MobMovementManager::PushMoveTo(MobMovementEntry &ent, float x, float y, float z, MobMovementMode mob_movement_mode)
|
||||
{
|
||||
ent.Commands.emplace_back(std::unique_ptr<IMovementCommand>(new MoveToCommand(x, y, z, mob_movement_mode)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ent
|
||||
* @param x
|
||||
* @param y
|
||||
* @param z
|
||||
* @param mob_movement_mode
|
||||
*/
|
||||
void MobMovementManager::PushSwimTo(MobMovementEntry &ent, float x, float y, float z, MobMovementMode mob_movement_mode)
|
||||
{
|
||||
ent.Commands.emplace_back(std::unique_ptr<IMovementCommand>(new SwimToCommand(x, y, z, mob_movement_mode)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ent
|
||||
* @param who
|
||||
* @param to
|
||||
* @param mob_movement_mode
|
||||
*/
|
||||
void MobMovementManager::PushRotateTo(MobMovementEntry &ent, Mob *who, float to, MobMovementMode mob_movement_mode)
|
||||
{
|
||||
auto from = FixHeading(who->GetHeading());
|
||||
@@ -1450,41 +1334,21 @@ void MobMovementManager::PushRotateTo(MobMovementEntry &ent, Mob *who, float to,
|
||||
ent.Commands.emplace_back(std::unique_ptr<IMovementCommand>(new RotateToCommand(to, diff > 0 ? 1.0 : -1.0, mob_movement_mode)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ent
|
||||
* @param x
|
||||
* @param y
|
||||
* @param z
|
||||
* @param mob_movement_mode
|
||||
*/
|
||||
void MobMovementManager::PushFlyTo(MobMovementEntry &ent, float x, float y, float z, MobMovementMode mob_movement_mode)
|
||||
{
|
||||
ent.Commands.emplace_back(std::unique_ptr<IMovementCommand>(new FlyToCommand(x, y, z, mob_movement_mode)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mob_movement_entry
|
||||
*/
|
||||
void MobMovementManager::PushStopMoving(MobMovementEntry &mob_movement_entry)
|
||||
{
|
||||
mob_movement_entry.Commands.emplace_back(std::unique_ptr<IMovementCommand>(new StopMovingCommand()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mob_movement_entry
|
||||
*/
|
||||
void MobMovementManager::PushEvadeCombat(MobMovementEntry &mob_movement_entry)
|
||||
{
|
||||
mob_movement_entry.Commands.emplace_back(std::unique_ptr<IMovementCommand>(new EvadeCombatCommand()));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param who
|
||||
* @param x
|
||||
* @param y
|
||||
* @param z
|
||||
* @param mob_movement_mode
|
||||
*/
|
||||
void MobMovementManager::HandleStuckBehavior(Mob *who, float x, float y, float z, MobMovementMode mob_movement_mode)
|
||||
{
|
||||
LogDebug("Handle stuck behavior for {0} at ({1}, {2}, {3}) with movement_mode {4}", who->GetName(), x, y, z, static_cast<int>(mob_movement_mode));
|
||||
|
||||
+34
-25
@@ -601,28 +601,8 @@ bool NPC::Process()
|
||||
DepopSwarmPets();
|
||||
}
|
||||
|
||||
if (mob_close_scan_timer.Check()) {
|
||||
entity_list.ScanCloseMobs(close_mobs, this, IsMoving());
|
||||
}
|
||||
|
||||
const uint16 npc_mob_close_scan_timer_moving = 6000;
|
||||
const uint16 npc_mob_close_scan_timer_idle = 60000;
|
||||
|
||||
if (mob_check_moving_timer.Check()) {
|
||||
if (moving) {
|
||||
if (mob_close_scan_timer.GetRemainingTime() > npc_mob_close_scan_timer_moving) {
|
||||
LogAIScanCloseDetail("NPC [{}] Restarting with moving timer", GetCleanName());
|
||||
mob_close_scan_timer.Disable();
|
||||
mob_close_scan_timer.Start(npc_mob_close_scan_timer_moving);
|
||||
mob_close_scan_timer.Trigger();
|
||||
}
|
||||
}
|
||||
else if (mob_close_scan_timer.GetDuration() == npc_mob_close_scan_timer_moving) {
|
||||
LogAIScanCloseDetail("NPC [{}] Restarting with idle timer", GetCleanName());
|
||||
mob_close_scan_timer.Disable();
|
||||
mob_close_scan_timer.Start(npc_mob_close_scan_timer_idle);
|
||||
}
|
||||
}
|
||||
ScanCloseMobProcess();
|
||||
CheckScanCloseMobsMovingTimer();
|
||||
|
||||
if (hp_regen_per_second > 0 && hp_regen_per_second_timer.Check()) {
|
||||
if (GetHP() < GetMaxHP()) {
|
||||
@@ -799,6 +779,11 @@ bool NPC::Process()
|
||||
}
|
||||
}
|
||||
|
||||
if (bot_attack_flag_timer.Check()) {
|
||||
bot_attack_flag_timer.Disable();
|
||||
ClearBotAttackFlags();
|
||||
}
|
||||
|
||||
AI_Process();
|
||||
|
||||
return true;
|
||||
@@ -3322,7 +3307,7 @@ bool NPC::AICheckCloseBeneficialSpells(
|
||||
/**
|
||||
* Check through close range mobs
|
||||
*/
|
||||
for (auto & close_mob : entity_list.GetCloseMobList(caster, cast_range)) {
|
||||
for (auto & close_mob : caster->GetCloseMobList(cast_range)) {
|
||||
Mob *mob = close_mob.second;
|
||||
if (!mob) {
|
||||
continue;
|
||||
@@ -3401,8 +3386,8 @@ void NPC::AIYellForHelp(Mob *sender, Mob *attacker)
|
||||
GetID()
|
||||
);
|
||||
|
||||
for (auto &close_mob : entity_list.GetCloseMobList(sender)) {
|
||||
Mob *mob = close_mob.second;
|
||||
for (auto &close_mob: sender->GetCloseMobList()) {
|
||||
Mob *mob = close_mob.second;
|
||||
if (!mob) {
|
||||
continue;
|
||||
}
|
||||
@@ -4014,3 +3999,27 @@ void NPC::DescribeSpecialAbilities(Client* c)
|
||||
c->Message(Chat::White, e.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void NPC::DoNpcToNpcAggroScan()
|
||||
{
|
||||
for (auto &close_mob : GetCloseMobList(GetAggroRange())) {
|
||||
Mob *mob = close_mob.second;
|
||||
if (!mob) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!mob->IsNPC()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (CheckWillAggro(mob)) {
|
||||
AddToHateList(mob);
|
||||
}
|
||||
}
|
||||
|
||||
AI_scan_area_timer->Disable();
|
||||
AI_scan_area_timer->Start(
|
||||
RandomTimer(RuleI(NPC, NPCToNPCAggroTimerMin), RuleI(NPC, NPCToNPCAggroTimerMax)),
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
@@ -557,6 +557,7 @@ public:
|
||||
|
||||
bool CanPathTo(float x, float y, float z);
|
||||
|
||||
void DoNpcToNpcAggroScan();
|
||||
protected:
|
||||
|
||||
void HandleRoambox();
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
#ifndef EQEMU_ZONE_PCH_H
|
||||
#define EQEMU_ZONE_PCH_H
|
||||
|
||||
#include "../quest_parser_collection.h"
|
||||
#include "../mob.h"
|
||||
#include "../npc.h"
|
||||
#include "../corpse.h"
|
||||
#include "../doors.h"
|
||||
#include "../bot.h"
|
||||
#include "../entity.h"
|
||||
#include "../client.h"
|
||||
#include "../zone.h"
|
||||
|
||||
// perl
|
||||
|
||||
#include "../embperl.h"
|
||||
|
||||
// lua
|
||||
#include "lua.hpp"
|
||||
#include <luabind/luabind.hpp>
|
||||
#include <luabind/object.hpp>
|
||||
#include <luabind/class.hpp>
|
||||
|
||||
#include "../lua_object.h"
|
||||
#include "../lua_spell.h"
|
||||
#include "../lua_item.h"
|
||||
#include "../lua_bit.h"
|
||||
#include "../lua_mob.h"
|
||||
#include "../lua_packet.h"
|
||||
#include "../lua_npc.h"
|
||||
#include "../lua_expedition.h"
|
||||
#include "../lua_mod.h"
|
||||
#include "../lua_inventory.h"
|
||||
#include "../lua_encounter.h"
|
||||
#include "../lua_raid.h"
|
||||
#include "../lua_client.h"
|
||||
#include "../lua_bot.h"
|
||||
#include "../lua_general.h"
|
||||
#include "../lua_entity.h"
|
||||
#include "../lua_ptr.h"
|
||||
#include "../lua_spawn.h"
|
||||
#include "../lua_iteminst.h"
|
||||
#include "../lua_group.h"
|
||||
#include "../lua_hate_list.h"
|
||||
#include "../lua_corpse.h"
|
||||
#include "../lua_buff.h"
|
||||
#include "../lua_entity_list.h"
|
||||
#include "../lua_parser.h"
|
||||
#include "../lua_door.h"
|
||||
#include "../lua_parser_events.h"
|
||||
#include "../lua_stat_bonuses.h"
|
||||
|
||||
#endif //EQEMU_ZONE_PCH_H
|
||||
+1
-2
@@ -2473,8 +2473,7 @@ bool Mob::SpellFinished(uint16 spell_id, Mob *spell_target, CastingSlot slot, in
|
||||
//Guard Assist Code
|
||||
if (RuleB(Character, PVPEnableGuardFactionAssist) && spell_target && IsDetrimentalSpell(spell_id) && spell_target != this) {
|
||||
if (IsClient() && spell_target->IsClient()|| (HasOwner() && GetOwner()->IsClient() && spell_target->IsClient())) {
|
||||
auto& mob_list = entity_list.GetCloseMobList(spell_target);
|
||||
for (auto& e : mob_list) {
|
||||
for (auto& e : spell_target->GetCloseMobList()) {
|
||||
auto mob = e.second;
|
||||
if (!mob) {
|
||||
continue;
|
||||
|
||||
Reference in New Issue
Block a user