mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-30 11:45:46 +00:00
Compare commits
55 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9c3498b431 | |||
| d7e09a1f3b | |||
| 1652e7a976 | |||
| 37dda9bf41 | |||
| a2b78ff4e6 | |||
| 79a3ce8d7e | |||
| d857fb3c48 | |||
| 2b4cd292e4 | |||
| 3b7cfa6454 | |||
| c5fa7e28c8 | |||
| 5d133a2b47 | |||
| 7122ac33b2 | |||
| c47644ea46 | |||
| a61f951d0e | |||
| 4357b8c731 | |||
| 9cbe25f712 | |||
| c14a17e4de | |||
| ab04a4c6df | |||
| c0cf9bb5aa | |||
| b5d23389ee | |||
| dc35ab5251 | |||
| 9cbfd5c8f0 | |||
| 5631a0711f | |||
| 00e02b61ca | |||
| 108397b138 | |||
| 9a07142a9b | |||
| 919a92bda3 | |||
| 140aba9f69 | |||
| c3d41e08f4 | |||
| 5d6a1aad50 | |||
| af91b2b41c | |||
| 2660aa79ab | |||
| 730738faf9 | |||
| 2bb7bba724 | |||
| e93081dde0 | |||
| 3a46bf7383 | |||
| aa6421afdf | |||
| 6a7eaae122 | |||
| 714b474d2c | |||
| e24d82f0fe | |||
| 33a375677e | |||
| 8fce86c396 | |||
| 68b40f0239 | |||
| 2dc2bac456 | |||
| 00a8a0cf88 | |||
| 5a466da96c | |||
| de4f5ae491 | |||
| fb20d92166 | |||
| 6cff433d23 | |||
| 2da7ddad57 | |||
| 55161e18c8 | |||
| 063d4fbd1a | |||
| c25cb0cc23 | |||
| ddac326239 | |||
| 14fe396510 |
+129
@@ -1,3 +1,132 @@
|
||||
## [22.25.0] - 08/28/2023
|
||||
|
||||
### Bots
|
||||
|
||||
* Add Support for Mana Pool AA Bonuses. ([#3571](https://github.com/EQEmu/Server/pull/3571)) @Aeadoin 2023-08-21
|
||||
* Remove In-Game Command References to Bot Groups ([#3545](https://github.com/EQEmu/Server/pull/3545)) @Aeadoin 2023-08-13
|
||||
|
||||
### Bug
|
||||
|
||||
* Escape item name in trader audit. ([#3540](https://github.com/EQEmu/Server/pull/3540)) @fryguy503 2023-08-13
|
||||
|
||||
### CMake
|
||||
|
||||
* Add cmake option to re-enable MSVC warnings ([#3537](https://github.com/EQEmu/Server/pull/3537)) @hgtw 2023-08-13
|
||||
* Define perlbind option for all targets ([#3538](https://github.com/EQEmu/Server/pull/3538)) @hgtw 2023-08-13
|
||||
|
||||
### Charm
|
||||
|
||||
* Fix to update target windows on charm on/off ([#3549](https://github.com/EQEmu/Server/pull/3549)) @noudess 2023-08-20
|
||||
|
||||
### Combat Messages
|
||||
|
||||
* Fix issue where pet proc damage was not showing up ([#3551](https://github.com/EQEmu/Server/pull/3551)) @noudess 2023-08-24
|
||||
|
||||
### Database
|
||||
|
||||
* Change primary key entry to NOT NULL ([#3559](https://github.com/EQEmu/Server/pull/3559)) @joligario 2023-08-20
|
||||
* Extend dumper CLI utility to export static instance data ([#3562](https://github.com/EQEmu/Server/pull/3562)) @Akkadius 2023-08-20
|
||||
|
||||
### Expansions
|
||||
|
||||
* Expansion settings tweaks ([#3556](https://github.com/EQEmu/Server/pull/3556)) @Akkadius 2023-08-20
|
||||
|
||||
### Feature
|
||||
|
||||
* Add adjustability for AERampage Range. ([#3548](https://github.com/EQEmu/Server/pull/3548)) @fryguy503 2023-08-20
|
||||
* Change #reload zone to reload zone headers globally. ([#3557](https://github.com/EQEmu/Server/pull/3557)) @Kinglykrab 2023-08-20
|
||||
* Change money type to all lower case as EQ live money shares and split has it that way. ([#3550](https://github.com/EQEmu/Server/pull/3550)) @regneq 2023-08-18
|
||||
|
||||
### Fixes
|
||||
|
||||
* Add character_stats_record to player tables @Akkadius 2023-08-11
|
||||
* Bots no longer drop group on death, and raid fixes. ([#3542](https://github.com/EQEmu/Server/pull/3542)) @Aeadoin 2023-08-13
|
||||
* Bots will now load AAs properly when spawned. ([#3544](https://github.com/EQEmu/Server/pull/3544)) @Aeadoin 2023-08-13
|
||||
* Clearing target window on CHARM wear off had a side effect ([#3570](https://github.com/EQEmu/Server/pull/3570)) @noudess 2023-08-21
|
||||
* Fix #motd/#set motd Command ([#3558](https://github.com/EQEmu/Server/pull/3558)) @Kinglykrab 2023-08-20
|
||||
* Fix Bot::CheckDataBucket to work with Owner Buckets. ([#3552](https://github.com/EQEmu/Server/pull/3552)) @Aeadoin 2023-08-18
|
||||
* Fix to zoning logging exception @Akkadius 2023-08-29
|
||||
* Instance GetUnusedInstanceID crash fox @Akkadius 2023-08-21
|
||||
* Minor adjustment to formula calc position to fix modifier bug. ([#3565](https://github.com/EQEmu/Server/pull/3565)) @Valorith 2023-08-21
|
||||
|
||||
### Instances
|
||||
|
||||
* Honor reserved instances ([#3563](https://github.com/EQEmu/Server/pull/3563)) @joligario 2023-08-21
|
||||
* Refine id selection ([#3568](https://github.com/EQEmu/Server/pull/3568)) @joligario 2023-08-29
|
||||
|
||||
### Logging
|
||||
|
||||
* Add detailed zoning logging ([#3555](https://github.com/EQEmu/Server/pull/3555)) @Akkadius 2023-08-20
|
||||
|
||||
### Quest API
|
||||
|
||||
* Reload content flags globally when a content flag is set ([#3564](https://github.com/EQEmu/Server/pull/3564)) @Akkadius 2023-08-21
|
||||
|
||||
### Rules
|
||||
|
||||
* Add FinalRaidExpMultiplier Rule ([#3554](https://github.com/EQEmu/Server/pull/3554)) @Valorith 2023-08-20
|
||||
* Add a rule to adjust the randomization range for Wizard\Caster Merc innate critical ratio. ([#3543](https://github.com/EQEmu/Server/pull/3543)) @catapultam-habeo 2023-08-13
|
||||
* Add rule to restrict hand in of quest items to quest flagged NPCs. ([#3536](https://github.com/EQEmu/Server/pull/3536)) @Valorith 2023-08-13
|
||||
* Add rule to toggle pets accepting quest items ([#3533](https://github.com/EQEmu/Server/pull/3533)) @Valorith 2023-08-06
|
||||
* Also reload rules in world when #reload rules invoked ([#3566](https://github.com/EQEmu/Server/pull/3566)) @Akkadius 2023-08-21
|
||||
* Correct explanation of Bots:ManaRegen ([#3569](https://github.com/EQEmu/Server/pull/3569)) @Aeadoin 2023-08-21
|
||||
|
||||
### Spawns
|
||||
|
||||
* Fixes a rarer issue where spawn2 is not being properly content filtered @Akkadius 2023-08-13
|
||||
|
||||
## [22.24.0] - 08/05/2023
|
||||
|
||||
### Character
|
||||
|
||||
* Record character stats to `character_stats_record` table ([#3522](https://github.com/EQEmu/Server/pull/3522)) @Akkadius 2023-08-05
|
||||
|
||||
### Code
|
||||
|
||||
* Cleanup #view zone_loot Command ([#3523](https://github.com/EQEmu/Server/pull/3523)) @Kinglykrab 2023-08-02
|
||||
* Remove Strings::Commify from all identifier values ([#3528](https://github.com/EQEmu/Server/pull/3528)) @Kinglykrab 2023-08-02
|
||||
|
||||
### Feature
|
||||
|
||||
* Add Support for Drakkin Heritage Illusions ([#3521](https://github.com/EQEmu/Server/pull/3521)) @Kinglykrab 2023-08-01
|
||||
|
||||
### Fixes
|
||||
|
||||
* Bug fix for raid mark NPC across zones ([#3525](https://github.com/EQEmu/Server/pull/3525)) @neckkola 2023-08-05
|
||||
* Bugs table should not target content database ([#3535](https://github.com/EQEmu/Server/pull/3535)) @Akkadius 2023-08-05
|
||||
* Fix +/- 0.1 XYZ Door Manipulation ([#3527](https://github.com/EQEmu/Server/pull/3527)) @Kinglykrab 2023-08-02
|
||||
* Fix issue with mob scanning when trying to use EVENT_SPAWN ([#3529](https://github.com/EQEmu/Server/pull/3529)) @Akkadius 2023-08-04
|
||||
|
||||
### Quest API
|
||||
|
||||
* Adjust GetCloseMobList calls internally ([#3530](https://github.com/EQEmu/Server/pull/3530)) @Akkadius 2023-08-04
|
||||
|
||||
## [22.23.0] - 07/31/2023
|
||||
|
||||
### Databuckets
|
||||
|
||||
* Improvements to distributed cache, reload commands ([#3519](https://github.com/EQEmu/Server/pull/3519)) @Akkadius 2023-08-01
|
||||
|
||||
### Fixes
|
||||
|
||||
* Fix #gm top level alias for #set gm ([#3517](https://github.com/EQEmu/Server/pull/3517)) @Kinglykrab 2023-07-30
|
||||
* Fix Appearance Issues ([#3520](https://github.com/EQEmu/Server/pull/3520)) @Kinglykrab 2023-08-01
|
||||
* Fix NPC Cast Events not parsing properly. ([#3518](https://github.com/EQEmu/Server/pull/3518)) @Kinglykrab 2023-08-01
|
||||
|
||||
### Scaling/Bug Fix
|
||||
|
||||
* Scaling where min and max damage was bugged ([#3514](https://github.com/EQEmu/Server/pull/3514)) @noudess 2023-08-01
|
||||
|
||||
## [22.22.1] - 07/30/2023
|
||||
|
||||
### Database
|
||||
|
||||
* Hotfix: Add command_subsettings to server tables @Akkadius 2023-07-29
|
||||
|
||||
### Doors
|
||||
|
||||
* Add door blacklist ([#3516](https://github.com/EQEmu/Server/pull/3516)) @Akkadius 2023-07-30
|
||||
|
||||
## [22.22.0] - 07/27/2023
|
||||
|
||||
### Code
|
||||
|
||||
+6
-1
@@ -32,7 +32,11 @@ IF(MSVC)
|
||||
ADD_DEFINITIONS(-D_HAS_AUTO_PTR_ETC) # for Luabind on C++17
|
||||
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
|
||||
ADD_DEFINITIONS( "/W0 /D_CRT_SECURE_NO_WARNINGS /wd4005 /wd4996 /nologo /Os")
|
||||
|
||||
OPTION(EQEMU_DISABLE_MSVC_WARNINGS "Disable MSVC compile warnings." ON)
|
||||
IF(EQEMU_DISABLE_MSVC_WARNINGS)
|
||||
ADD_DEFINITIONS( "/W0 /D_CRT_SECURE_NO_WARNINGS /wd4005 /wd4996 /nologo /Os")
|
||||
ENDIF(EQEMU_DISABLE_MSVC_WARNINGS)
|
||||
ELSE(MSVC)
|
||||
ADD_DEFINITIONS(-DHAS_UNION_SEMUN)
|
||||
ENDIF(MSVC)
|
||||
@@ -384,6 +388,7 @@ IF(PERL_LIBRARY_ENABLED)
|
||||
INCLUDE_DIRECTORIES(SYSTEM "${PERL_LIBRARY_INCLUDE}")
|
||||
ADD_DEFINITIONS(-DEMBPERL)
|
||||
ADD_DEFINITIONS(-DEMBPERL_PLUGIN)
|
||||
ADD_DEFINITIONS(-DPERLBIND_NO_STRICT_SCALAR_TYPES)
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
|
||||
@@ -279,6 +279,11 @@ void DatabaseDumpService::DatabaseDump()
|
||||
}
|
||||
}
|
||||
|
||||
if (IsDumpStaticInstanceData()) {
|
||||
tables_to_dump += "instance_list";
|
||||
options += " --no-create-info --where=\"instance_list.is_global > 0 and instance_list.never_expires > 0\"";
|
||||
}
|
||||
|
||||
if (!dump_descriptor.empty()) {
|
||||
SetDumpFileName(GetDumpFileName() + dump_descriptor);
|
||||
}
|
||||
@@ -606,3 +611,13 @@ void DatabaseDumpService::RemoveCredentialsFile()
|
||||
std::filesystem::remove(CREDENTIALS_FILE);
|
||||
}
|
||||
}
|
||||
|
||||
bool DatabaseDumpService::IsDumpStaticInstanceData()
|
||||
{
|
||||
return dump_static_instance_data;
|
||||
}
|
||||
|
||||
void DatabaseDumpService::SetDumpStaticInstanceData(bool b)
|
||||
{
|
||||
dump_static_instance_data = b;
|
||||
}
|
||||
|
||||
@@ -58,6 +58,9 @@ public:
|
||||
bool IsDumpMercTables() const;
|
||||
void SetDumpMercTables(bool dump_bot_tables);
|
||||
|
||||
void SetDumpStaticInstanceData(bool b);
|
||||
bool IsDumpStaticInstanceData();
|
||||
|
||||
private:
|
||||
bool dump_all_tables = false;
|
||||
bool dump_state_tables = false;
|
||||
@@ -73,6 +76,8 @@ private:
|
||||
bool dump_drop_table_syntax_only = false;
|
||||
bool dump_bot_tables = false;
|
||||
bool dump_merc_tables = false;
|
||||
bool dump_static_instance_data = false;
|
||||
|
||||
std::string dump_path;
|
||||
std::string dump_file_name;
|
||||
|
||||
|
||||
@@ -4825,6 +4825,111 @@ UPDATE data_buckets SET character_id = SUBSTRING_INDEX(SUBSTRING_INDEX( `key`, '
|
||||
UPDATE data_buckets SET npc_id = SUBSTRING_INDEX(SUBSTRING_INDEX( `key`, '-', 2 ), '-', -1), `key` = SUBSTR(SUBSTRING_INDEX(`key`, SUBSTRING_INDEX( `key`, '-', 2 ), -1), 2) WHERE `key` LIKE 'npc-%';
|
||||
UPDATE data_buckets SET bot_id = SUBSTRING_INDEX(SUBSTRING_INDEX( `key`, '-', 2 ), '-', -1), `key` = SUBSTR(SUBSTRING_INDEX(`key`, SUBSTRING_INDEX( `key`, '-', 2 ), -1), 2) WHERE `key` LIKE 'bot-%';
|
||||
|
||||
)"
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9234,
|
||||
.description = "2023_07_27_update_raid_details.sql",
|
||||
.check = "SHOW COLUMNS FROM `raid_details` LIKE 'marked_npc_1_entity_id';",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(ALTER TABLE `raid_details`
|
||||
CHANGE COLUMN `marked_npc_1` `marked_npc_1_entity_id` INT UNSIGNED NOT NULL DEFAULT '0' AFTER `motd`,
|
||||
ADD COLUMN `marked_npc_1_zone_id` INT UNSIGNED NOT NULL DEFAULT '0' AFTER `marked_npc_1_entity_id`,
|
||||
ADD COLUMN `marked_npc_1_instance_id` INT UNSIGNED NOT NULL DEFAULT '0' AFTER `marked_npc_1_zone_id`,
|
||||
CHANGE COLUMN `marked_npc_2` `marked_npc_2_entity_id` INT UNSIGNED NOT NULL DEFAULT '0' AFTER `marked_npc_1_instance_id`,
|
||||
ADD COLUMN `marked_npc_2_zone_id` INT UNSIGNED NOT NULL DEFAULT '0' AFTER `marked_npc_2_entity_id`,
|
||||
ADD COLUMN `marked_npc_2_instance_id` INT UNSIGNED NOT NULL DEFAULT '0' AFTER `marked_npc_2_zone_id`,
|
||||
CHANGE COLUMN `marked_npc_3` `marked_npc_3_entity_id` INT UNSIGNED NOT NULL DEFAULT '0' AFTER `marked_npc_2_instance_id`,
|
||||
ADD COLUMN `marked_npc_3_zone_id` INT UNSIGNED NOT NULL DEFAULT '0' AFTER `marked_npc_3_entity_id`,
|
||||
ADD COLUMN `marked_npc_3_instance_id` INT UNSIGNED NOT NULL DEFAULT '0' AFTER `marked_npc_3_zone_id`;
|
||||
)"
|
||||
},
|
||||
ManifestEntry{
|
||||
.version = 9235,
|
||||
.description = "2023_07_31_character_stats_record.sql",
|
||||
.check = "SHOW TABLES LIKE 'character_stats_record'",
|
||||
.condition = "empty",
|
||||
.match = "",
|
||||
.sql = R"(
|
||||
|
||||
CREATE TABLE `character_stats_record` (
|
||||
`character_id` int NOT NULL,
|
||||
`name` varchar(100) NULL,
|
||||
`status` int NULL DEFAULT 0,
|
||||
`level` int NULL DEFAULT 0,
|
||||
`class` int NULL DEFAULT 0,
|
||||
`race` int NULL DEFAULT 0,
|
||||
`aa_points` int NULL DEFAULT 0,
|
||||
`hp` bigint NULL DEFAULT 0,
|
||||
`mana` bigint NULL DEFAULT 0,
|
||||
`endurance` bigint NULL DEFAULT 0,
|
||||
`ac` int NULL DEFAULT 0,
|
||||
`strength` int NULL DEFAULT 0,
|
||||
`stamina` int NULL DEFAULT 0,
|
||||
`dexterity` int NULL DEFAULT 0,
|
||||
`agility` int NULL DEFAULT 0,
|
||||
`intelligence` int NULL DEFAULT 0,
|
||||
`wisdom` int NULL DEFAULT 0,
|
||||
`charisma` int NULL DEFAULT 0,
|
||||
`magic_resist` int NULL DEFAULT 0,
|
||||
`fire_resist` int NULL DEFAULT 0,
|
||||
`cold_resist` int NULL DEFAULT 0,
|
||||
`poison_resist` int NULL DEFAULT 0,
|
||||
`disease_resist` int NULL DEFAULT 0,
|
||||
`corruption_resist` int NULL DEFAULT 0,
|
||||
`heroic_strength` int NULL DEFAULT 0,
|
||||
`heroic_stamina` int NULL DEFAULT 0,
|
||||
`heroic_dexterity` int NULL DEFAULT 0,
|
||||
`heroic_agility` int NULL DEFAULT 0,
|
||||
`heroic_intelligence` int NULL DEFAULT 0,
|
||||
`heroic_wisdom` int NULL DEFAULT 0,
|
||||
`heroic_charisma` int NULL DEFAULT 0,
|
||||
`heroic_magic_resist` int NULL DEFAULT 0,
|
||||
`heroic_fire_resist` int NULL DEFAULT 0,
|
||||
`heroic_cold_resist` int NULL DEFAULT 0,
|
||||
`heroic_poison_resist` int NULL DEFAULT 0,
|
||||
`heroic_disease_resist` int NULL DEFAULT 0,
|
||||
`heroic_corruption_resist` int NULL DEFAULT 0,
|
||||
`haste` int NULL DEFAULT 0,
|
||||
`accuracy` int NULL DEFAULT 0,
|
||||
`attack` int NULL DEFAULT 0,
|
||||
`avoidance` int NULL DEFAULT 0,
|
||||
`clairvoyance` int NULL DEFAULT 0,
|
||||
`combat_effects` int NULL DEFAULT 0,
|
||||
`damage_shield_mitigation` int NULL DEFAULT 0,
|
||||
`damage_shield` int NULL DEFAULT 0,
|
||||
`dot_shielding` int NULL DEFAULT 0,
|
||||
`hp_regen` int NULL DEFAULT 0,
|
||||
`mana_regen` int NULL DEFAULT 0,
|
||||
`endurance_regen` int NULL DEFAULT 0,
|
||||
`shielding` int NULL DEFAULT 0,
|
||||
`spell_damage` int NULL DEFAULT 0,
|
||||
`spell_shielding` int NULL DEFAULT 0,
|
||||
`strikethrough` int NULL DEFAULT 0,
|
||||
`stun_resist` int NULL DEFAULT 0,
|
||||
`backstab` int NULL DEFAULT 0,
|
||||
`wind` int NULL DEFAULT 0,
|
||||
`brass` int NULL DEFAULT 0,
|
||||
`string` int NULL DEFAULT 0,
|
||||
`percussion` int NULL DEFAULT 0,
|
||||
`singing` int NULL DEFAULT 0,
|
||||
`baking` int NULL DEFAULT 0,
|
||||
`alchemy` int NULL DEFAULT 0,
|
||||
`tailoring` int NULL DEFAULT 0,
|
||||
`blacksmithing` int NULL DEFAULT 0,
|
||||
`fletching` int NULL DEFAULT 0,
|
||||
`brewing` int NULL DEFAULT 0,
|
||||
`jewelry` int NULL DEFAULT 0,
|
||||
`pottery` int NULL DEFAULT 0,
|
||||
`research` int NULL DEFAULT 0,
|
||||
`alcohol` int NULL DEFAULT 0,
|
||||
`fishing` int NULL DEFAULT 0,
|
||||
`tinkering` int NULL DEFAULT 0,
|
||||
`created_at` datetime DEFAULT NULL,
|
||||
`updated_at` datetime DEFAULT NULL,
|
||||
PRIMARY KEY (`character_id`)
|
||||
);
|
||||
)"
|
||||
},
|
||||
|
||||
|
||||
@@ -131,85 +131,118 @@ bool Database::CreateInstance(uint16 instance_id, uint32 zone_id, uint32 version
|
||||
bool Database::GetUnusedInstanceID(uint16 &instance_id)
|
||||
{
|
||||
uint32 max_reserved_instance_id = RuleI(Instances, ReservedInstances);
|
||||
uint32 max = 32000;
|
||||
uint32 max_instance_id = 32000;
|
||||
|
||||
// sanity check reserved
|
||||
if (max_reserved_instance_id >= max_instance_id) {
|
||||
instance_id = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
// recycle instances
|
||||
if (RuleB(Instances, RecycleInstanceIds)) {
|
||||
|
||||
//query to get first unused id above reserved
|
||||
auto query = fmt::format(
|
||||
SQL(
|
||||
SELECT id
|
||||
FROM instance_list
|
||||
WHERE id = {};
|
||||
),
|
||||
max_reserved_instance_id + 1
|
||||
);
|
||||
|
||||
auto results = QueryDatabase(query);
|
||||
|
||||
// could not successfully query - bail out
|
||||
if (!results.Success()) {
|
||||
instance_id = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
// first id is available
|
||||
if (results.RowCount() == 0) {
|
||||
instance_id = max_reserved_instance_id + 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
// now look for next available above reserved
|
||||
query = fmt::format(
|
||||
SQL(
|
||||
SELECT MIN(i.id + 1) AS next_available
|
||||
FROM instance_list i
|
||||
LEFT JOIN instance_list i2 ON i.id + 1 = i2.id
|
||||
WHERE i.id >= {}
|
||||
AND i2.id IS NULL;
|
||||
),
|
||||
max_reserved_instance_id
|
||||
);
|
||||
|
||||
results = QueryDatabase(query);
|
||||
|
||||
// could not successfully query - bail out
|
||||
if (!results.Success()) {
|
||||
instance_id = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
// did not retrieve any rows - bail out
|
||||
if (results.RowCount() == 0) {
|
||||
instance_id = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
auto row = results.begin();
|
||||
|
||||
// check that id is within limits
|
||||
if (row[0] && Strings::ToInt(row[0]) <= max_instance_id) {
|
||||
instance_id = Strings::ToInt(row[0]);
|
||||
return true;
|
||||
}
|
||||
|
||||
// no available instance ids
|
||||
instance_id = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
// get max unused id above reserved
|
||||
auto query = fmt::format(
|
||||
"SELECT IFNULL(MAX(id), {}) + 1 FROM instance_list WHERE id > {}",
|
||||
max_reserved_instance_id,
|
||||
max_reserved_instance_id
|
||||
);
|
||||
|
||||
if (RuleB(Instances, RecycleInstanceIds)) {
|
||||
query = (
|
||||
SQL(
|
||||
SELECT i.id + 1 AS next_available
|
||||
FROM instance_list i
|
||||
LEFT JOIN instance_list i2 ON i2.id = i.id + 1
|
||||
WHERE i2.id IS NULL
|
||||
ORDER BY i.id
|
||||
LIMIT 0, 1;
|
||||
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
auto results = QueryDatabase(query);
|
||||
|
||||
// could not successfully query - bail out
|
||||
if (!results.Success()) {
|
||||
instance_id = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
// did not retrieve any rows - bail out
|
||||
if (results.RowCount() == 0) {
|
||||
instance_id = max_reserved_instance_id;
|
||||
return true;
|
||||
instance_id = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
auto row = results.begin();
|
||||
|
||||
if (Strings::ToInt(row[0]) <= max) {
|
||||
// no instances currently used
|
||||
if (!row[0]) {
|
||||
instance_id = max_reserved_instance_id + 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
// check that id is within limits
|
||||
if (Strings::ToInt(row[0]) <= max_instance_id) {
|
||||
instance_id = Strings::ToInt(row[0]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (instance_id < max_reserved_instance_id) {
|
||||
instance_id = max_reserved_instance_id;
|
||||
return true;
|
||||
}
|
||||
|
||||
query = fmt::format("SELECT id FROM instance_list where id > {} ORDER BY id", max_reserved_instance_id);
|
||||
results = QueryDatabase(query);
|
||||
|
||||
if (!results.Success()) {
|
||||
instance_id = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (results.RowCount() == 0) {
|
||||
instance_id = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
max_reserved_instance_id++;
|
||||
|
||||
for (auto row : results) {
|
||||
if (max_reserved_instance_id < Strings::ToUnsignedInt(row[0])) {
|
||||
instance_id = max_reserved_instance_id;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (max_reserved_instance_id > max) {
|
||||
instance_id = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
max_reserved_instance_id++;
|
||||
}
|
||||
|
||||
instance_id = max_reserved_instance_id;
|
||||
|
||||
return true;
|
||||
// no available instance ids
|
||||
instance_id = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Database::IsGlobalInstance(uint16 instance_id)
|
||||
|
||||
@@ -66,6 +66,7 @@ namespace DatabaseSchema {
|
||||
{"character_potionbelt", "id"},
|
||||
{"character_skills", "id"},
|
||||
{"character_spells", "id"},
|
||||
{"character_stats_record", "character_id"},
|
||||
{"character_task_timers", "character_id"},
|
||||
{"character_tasks", "charid"},
|
||||
{"character_tribute", "character_id"},
|
||||
@@ -134,6 +135,7 @@ namespace DatabaseSchema {
|
||||
"character_potionbelt",
|
||||
"character_skills",
|
||||
"character_spells",
|
||||
"character_stats_record",
|
||||
"character_task_timers",
|
||||
"character_tasks",
|
||||
"character_tribute",
|
||||
@@ -258,6 +260,7 @@ namespace DatabaseSchema {
|
||||
"chatchannels",
|
||||
"chatchannel_reserved_names",
|
||||
"command_settings",
|
||||
"command_subsettings",
|
||||
"content_flags",
|
||||
"db_str",
|
||||
"eqtime",
|
||||
|
||||
@@ -138,6 +138,7 @@ namespace Logs {
|
||||
QuestErrors,
|
||||
PlayerEvents,
|
||||
DataBuckets,
|
||||
Zoning,
|
||||
MaxCategoryID /* Don't Remove this */
|
||||
};
|
||||
|
||||
@@ -235,6 +236,7 @@ namespace Logs {
|
||||
"QuestErrors",
|
||||
"PlayerEvents",
|
||||
"DataBuckets",
|
||||
"Zoning",
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -804,6 +804,16 @@
|
||||
OutF(LogSys, Logs::Detail, Logs::DataBuckets, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogZoning(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::General, Logs::Zoning))\
|
||||
OutF(LogSys, Logs::General, Logs::Zoning, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogZoningDetail(message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(Logs::Detail, Logs::Zoning))\
|
||||
OutF(LogSys, Logs::Detail, Logs::Zoning, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define Log(debug_level, log_category, message, ...) do {\
|
||||
if (LogSys.IsLogEnabled(debug_level, log_category))\
|
||||
LogSys.Out(debug_level, log_category, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
|
||||
@@ -230,6 +230,10 @@ bool EQ::ItemData::IsTypeShield() const
|
||||
return (ItemType == item::ItemTypeShield);
|
||||
}
|
||||
|
||||
bool EQ::ItemData::IsQuestItem() const {
|
||||
return QuestItemFlag;
|
||||
}
|
||||
|
||||
bool EQ::ItemData::CheckLoreConflict(const ItemData* l_item, const ItemData* r_item)
|
||||
{
|
||||
if (!l_item || !r_item)
|
||||
|
||||
@@ -546,6 +546,7 @@ namespace EQ
|
||||
bool IsType1HWeapon() const;
|
||||
bool IsType2HWeapon() const;
|
||||
bool IsTypeShield() const;
|
||||
bool IsQuestItem() const;
|
||||
|
||||
static bool CheckLoreConflict(const ItemData* l_item, const ItemData* r_item);
|
||||
bool CheckLoreConflict(const ItemData* item) const { return CheckLoreConflict(this, item); }
|
||||
|
||||
+4
-2
@@ -1594,11 +1594,13 @@ float GetRaceGenderDefaultHeight(int race, int gender)
|
||||
|
||||
const auto size = sizeof(male_height) / sizeof(male_height[0]);
|
||||
|
||||
if (race >= size)
|
||||
if (race >= size) {
|
||||
return 6.0f;
|
||||
}
|
||||
|
||||
if (gender == 1)
|
||||
if (gender == FEMALE) {
|
||||
return female_height[race];
|
||||
}
|
||||
|
||||
return male_height[race];
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -24,9 +24,15 @@ public:
|
||||
int32_t loottype;
|
||||
int8_t locked;
|
||||
std::string motd;
|
||||
uint16_t marked_npc_1;
|
||||
uint16_t marked_npc_2;
|
||||
uint16_t marked_npc_3;
|
||||
uint32_t marked_npc_1_entity_id;
|
||||
uint32_t marked_npc_1_zone_id;
|
||||
uint32_t marked_npc_1_instance_id;
|
||||
uint32_t marked_npc_2_entity_id;
|
||||
uint32_t marked_npc_2_zone_id;
|
||||
uint32_t marked_npc_2_instance_id;
|
||||
uint32_t marked_npc_3_entity_id;
|
||||
uint32_t marked_npc_3_zone_id;
|
||||
uint32_t marked_npc_3_instance_id;
|
||||
};
|
||||
|
||||
static std::string PrimaryKey()
|
||||
@@ -41,9 +47,15 @@ public:
|
||||
"loottype",
|
||||
"locked",
|
||||
"motd",
|
||||
"marked_npc_1",
|
||||
"marked_npc_2",
|
||||
"marked_npc_3",
|
||||
"marked_npc_1_entity_id",
|
||||
"marked_npc_1_zone_id",
|
||||
"marked_npc_1_instance_id",
|
||||
"marked_npc_2_entity_id",
|
||||
"marked_npc_2_zone_id",
|
||||
"marked_npc_2_instance_id",
|
||||
"marked_npc_3_entity_id",
|
||||
"marked_npc_3_zone_id",
|
||||
"marked_npc_3_instance_id",
|
||||
};
|
||||
}
|
||||
|
||||
@@ -54,9 +66,15 @@ public:
|
||||
"loottype",
|
||||
"locked",
|
||||
"motd",
|
||||
"marked_npc_1",
|
||||
"marked_npc_2",
|
||||
"marked_npc_3",
|
||||
"marked_npc_1_entity_id",
|
||||
"marked_npc_1_zone_id",
|
||||
"marked_npc_1_instance_id",
|
||||
"marked_npc_2_entity_id",
|
||||
"marked_npc_2_zone_id",
|
||||
"marked_npc_2_instance_id",
|
||||
"marked_npc_3_entity_id",
|
||||
"marked_npc_3_zone_id",
|
||||
"marked_npc_3_instance_id",
|
||||
};
|
||||
}
|
||||
|
||||
@@ -97,13 +115,19 @@ public:
|
||||
{
|
||||
RaidDetails e{};
|
||||
|
||||
e.raidid = 0;
|
||||
e.loottype = 0;
|
||||
e.locked = 0;
|
||||
e.motd = "";
|
||||
e.marked_npc_1 = 0;
|
||||
e.marked_npc_2 = 0;
|
||||
e.marked_npc_3 = 0;
|
||||
e.raidid = 0;
|
||||
e.loottype = 0;
|
||||
e.locked = 0;
|
||||
e.motd = "";
|
||||
e.marked_npc_1_entity_id = 0;
|
||||
e.marked_npc_1_zone_id = 0;
|
||||
e.marked_npc_1_instance_id = 0;
|
||||
e.marked_npc_2_entity_id = 0;
|
||||
e.marked_npc_2_zone_id = 0;
|
||||
e.marked_npc_2_instance_id = 0;
|
||||
e.marked_npc_3_entity_id = 0;
|
||||
e.marked_npc_3_zone_id = 0;
|
||||
e.marked_npc_3_instance_id = 0;
|
||||
|
||||
return e;
|
||||
}
|
||||
@@ -140,13 +164,19 @@ public:
|
||||
if (results.RowCount() == 1) {
|
||||
RaidDetails e{};
|
||||
|
||||
e.raidid = static_cast<int32_t>(atoi(row[0]));
|
||||
e.loottype = static_cast<int32_t>(atoi(row[1]));
|
||||
e.locked = static_cast<int8_t>(atoi(row[2]));
|
||||
e.motd = row[3] ? row[3] : "";
|
||||
e.marked_npc_1 = static_cast<uint16_t>(strtoul(row[4], nullptr, 10));
|
||||
e.marked_npc_2 = static_cast<uint16_t>(strtoul(row[5], nullptr, 10));
|
||||
e.marked_npc_3 = static_cast<uint16_t>(strtoul(row[6], nullptr, 10));
|
||||
e.raidid = static_cast<int32_t>(atoi(row[0]));
|
||||
e.loottype = static_cast<int32_t>(atoi(row[1]));
|
||||
e.locked = static_cast<int8_t>(atoi(row[2]));
|
||||
e.motd = row[3] ? row[3] : "";
|
||||
e.marked_npc_1_entity_id = static_cast<uint32_t>(strtoul(row[4], nullptr, 10));
|
||||
e.marked_npc_1_zone_id = static_cast<uint32_t>(strtoul(row[5], nullptr, 10));
|
||||
e.marked_npc_1_instance_id = static_cast<uint32_t>(strtoul(row[6], nullptr, 10));
|
||||
e.marked_npc_2_entity_id = static_cast<uint32_t>(strtoul(row[7], nullptr, 10));
|
||||
e.marked_npc_2_zone_id = static_cast<uint32_t>(strtoul(row[8], nullptr, 10));
|
||||
e.marked_npc_2_instance_id = static_cast<uint32_t>(strtoul(row[9], nullptr, 10));
|
||||
e.marked_npc_3_entity_id = static_cast<uint32_t>(strtoul(row[10], nullptr, 10));
|
||||
e.marked_npc_3_zone_id = static_cast<uint32_t>(strtoul(row[11], nullptr, 10));
|
||||
e.marked_npc_3_instance_id = static_cast<uint32_t>(strtoul(row[12], nullptr, 10));
|
||||
|
||||
return e;
|
||||
}
|
||||
@@ -184,9 +214,15 @@ public:
|
||||
v.push_back(columns[1] + " = " + std::to_string(e.loottype));
|
||||
v.push_back(columns[2] + " = " + std::to_string(e.locked));
|
||||
v.push_back(columns[3] + " = '" + Strings::Escape(e.motd) + "'");
|
||||
v.push_back(columns[4] + " = " + std::to_string(e.marked_npc_1));
|
||||
v.push_back(columns[5] + " = " + std::to_string(e.marked_npc_2));
|
||||
v.push_back(columns[6] + " = " + std::to_string(e.marked_npc_3));
|
||||
v.push_back(columns[4] + " = " + std::to_string(e.marked_npc_1_entity_id));
|
||||
v.push_back(columns[5] + " = " + std::to_string(e.marked_npc_1_zone_id));
|
||||
v.push_back(columns[6] + " = " + std::to_string(e.marked_npc_1_instance_id));
|
||||
v.push_back(columns[7] + " = " + std::to_string(e.marked_npc_2_entity_id));
|
||||
v.push_back(columns[8] + " = " + std::to_string(e.marked_npc_2_zone_id));
|
||||
v.push_back(columns[9] + " = " + std::to_string(e.marked_npc_2_instance_id));
|
||||
v.push_back(columns[10] + " = " + std::to_string(e.marked_npc_3_entity_id));
|
||||
v.push_back(columns[11] + " = " + std::to_string(e.marked_npc_3_zone_id));
|
||||
v.push_back(columns[12] + " = " + std::to_string(e.marked_npc_3_instance_id));
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
@@ -212,9 +248,15 @@ public:
|
||||
v.push_back(std::to_string(e.loottype));
|
||||
v.push_back(std::to_string(e.locked));
|
||||
v.push_back("'" + Strings::Escape(e.motd) + "'");
|
||||
v.push_back(std::to_string(e.marked_npc_1));
|
||||
v.push_back(std::to_string(e.marked_npc_2));
|
||||
v.push_back(std::to_string(e.marked_npc_3));
|
||||
v.push_back(std::to_string(e.marked_npc_1_entity_id));
|
||||
v.push_back(std::to_string(e.marked_npc_1_zone_id));
|
||||
v.push_back(std::to_string(e.marked_npc_1_instance_id));
|
||||
v.push_back(std::to_string(e.marked_npc_2_entity_id));
|
||||
v.push_back(std::to_string(e.marked_npc_2_zone_id));
|
||||
v.push_back(std::to_string(e.marked_npc_2_instance_id));
|
||||
v.push_back(std::to_string(e.marked_npc_3_entity_id));
|
||||
v.push_back(std::to_string(e.marked_npc_3_zone_id));
|
||||
v.push_back(std::to_string(e.marked_npc_3_instance_id));
|
||||
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
@@ -248,9 +290,15 @@ public:
|
||||
v.push_back(std::to_string(e.loottype));
|
||||
v.push_back(std::to_string(e.locked));
|
||||
v.push_back("'" + Strings::Escape(e.motd) + "'");
|
||||
v.push_back(std::to_string(e.marked_npc_1));
|
||||
v.push_back(std::to_string(e.marked_npc_2));
|
||||
v.push_back(std::to_string(e.marked_npc_3));
|
||||
v.push_back(std::to_string(e.marked_npc_1_entity_id));
|
||||
v.push_back(std::to_string(e.marked_npc_1_zone_id));
|
||||
v.push_back(std::to_string(e.marked_npc_1_instance_id));
|
||||
v.push_back(std::to_string(e.marked_npc_2_entity_id));
|
||||
v.push_back(std::to_string(e.marked_npc_2_zone_id));
|
||||
v.push_back(std::to_string(e.marked_npc_2_instance_id));
|
||||
v.push_back(std::to_string(e.marked_npc_3_entity_id));
|
||||
v.push_back(std::to_string(e.marked_npc_3_zone_id));
|
||||
v.push_back(std::to_string(e.marked_npc_3_instance_id));
|
||||
|
||||
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||
}
|
||||
@@ -284,13 +332,19 @@ public:
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
RaidDetails e{};
|
||||
|
||||
e.raidid = static_cast<int32_t>(atoi(row[0]));
|
||||
e.loottype = static_cast<int32_t>(atoi(row[1]));
|
||||
e.locked = static_cast<int8_t>(atoi(row[2]));
|
||||
e.motd = row[3] ? row[3] : "";
|
||||
e.marked_npc_1 = static_cast<uint16_t>(strtoul(row[4], nullptr, 10));
|
||||
e.marked_npc_2 = static_cast<uint16_t>(strtoul(row[5], nullptr, 10));
|
||||
e.marked_npc_3 = static_cast<uint16_t>(strtoul(row[6], nullptr, 10));
|
||||
e.raidid = static_cast<int32_t>(atoi(row[0]));
|
||||
e.loottype = static_cast<int32_t>(atoi(row[1]));
|
||||
e.locked = static_cast<int8_t>(atoi(row[2]));
|
||||
e.motd = row[3] ? row[3] : "";
|
||||
e.marked_npc_1_entity_id = static_cast<uint32_t>(strtoul(row[4], nullptr, 10));
|
||||
e.marked_npc_1_zone_id = static_cast<uint32_t>(strtoul(row[5], nullptr, 10));
|
||||
e.marked_npc_1_instance_id = static_cast<uint32_t>(strtoul(row[6], nullptr, 10));
|
||||
e.marked_npc_2_entity_id = static_cast<uint32_t>(strtoul(row[7], nullptr, 10));
|
||||
e.marked_npc_2_zone_id = static_cast<uint32_t>(strtoul(row[8], nullptr, 10));
|
||||
e.marked_npc_2_instance_id = static_cast<uint32_t>(strtoul(row[9], nullptr, 10));
|
||||
e.marked_npc_3_entity_id = static_cast<uint32_t>(strtoul(row[10], nullptr, 10));
|
||||
e.marked_npc_3_zone_id = static_cast<uint32_t>(strtoul(row[11], nullptr, 10));
|
||||
e.marked_npc_3_instance_id = static_cast<uint32_t>(strtoul(row[12], nullptr, 10));
|
||||
|
||||
all_entries.push_back(e);
|
||||
}
|
||||
@@ -315,13 +369,19 @@ public:
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
RaidDetails e{};
|
||||
|
||||
e.raidid = static_cast<int32_t>(atoi(row[0]));
|
||||
e.loottype = static_cast<int32_t>(atoi(row[1]));
|
||||
e.locked = static_cast<int8_t>(atoi(row[2]));
|
||||
e.motd = row[3] ? row[3] : "";
|
||||
e.marked_npc_1 = static_cast<uint16_t>(strtoul(row[4], nullptr, 10));
|
||||
e.marked_npc_2 = static_cast<uint16_t>(strtoul(row[5], nullptr, 10));
|
||||
e.marked_npc_3 = static_cast<uint16_t>(strtoul(row[6], nullptr, 10));
|
||||
e.raidid = static_cast<int32_t>(atoi(row[0]));
|
||||
e.loottype = static_cast<int32_t>(atoi(row[1]));
|
||||
e.locked = static_cast<int8_t>(atoi(row[2]));
|
||||
e.motd = row[3] ? row[3] : "";
|
||||
e.marked_npc_1_entity_id = static_cast<uint32_t>(strtoul(row[4], nullptr, 10));
|
||||
e.marked_npc_1_zone_id = static_cast<uint32_t>(strtoul(row[5], nullptr, 10));
|
||||
e.marked_npc_1_instance_id = static_cast<uint32_t>(strtoul(row[6], nullptr, 10));
|
||||
e.marked_npc_2_entity_id = static_cast<uint32_t>(strtoul(row[7], nullptr, 10));
|
||||
e.marked_npc_2_zone_id = static_cast<uint32_t>(strtoul(row[8], nullptr, 10));
|
||||
e.marked_npc_2_instance_id = static_cast<uint32_t>(strtoul(row[9], nullptr, 10));
|
||||
e.marked_npc_3_entity_id = static_cast<uint32_t>(strtoul(row[10], nullptr, 10));
|
||||
e.marked_npc_3_zone_id = static_cast<uint32_t>(strtoul(row[11], nullptr, 10));
|
||||
e.marked_npc_3_instance_id = static_cast<uint32_t>(strtoul(row[12], nullptr, 10));
|
||||
|
||||
all_entries.push_back(e);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
#ifndef EQEMU_CHARACTER_STATS_RECORD_REPOSITORY_H
|
||||
#define EQEMU_CHARACTER_STATS_RECORD_REPOSITORY_H
|
||||
|
||||
#include "../database.h"
|
||||
#include "../strings.h"
|
||||
#include "base/base_character_stats_record_repository.h"
|
||||
|
||||
class CharacterStatsRecordRepository: public BaseCharacterStatsRecordRepository {
|
||||
public:
|
||||
|
||||
/**
|
||||
* This file was auto generated and can be modified and extended upon
|
||||
*
|
||||
* Base repository methods are automatically
|
||||
* generated in the "base" version of this repository. The base repository
|
||||
* is immutable and to be left untouched, while methods in this class
|
||||
* are used as extension methods for more specific persistence-layer
|
||||
* accessors or mutators.
|
||||
*
|
||||
* Base Methods (Subject to be expanded upon in time)
|
||||
*
|
||||
* Note: Not all tables are designed appropriately to fit functionality with all base methods
|
||||
*
|
||||
* InsertOne
|
||||
* UpdateOne
|
||||
* DeleteOne
|
||||
* FindOne
|
||||
* GetWhere(std::string where_filter)
|
||||
* DeleteWhere(std::string where_filter)
|
||||
* InsertMany
|
||||
* All
|
||||
*
|
||||
* Example custom methods in a repository
|
||||
*
|
||||
* CharacterStatsRecordRepository::GetByZoneAndVersion(int zone_id, int zone_version)
|
||||
* CharacterStatsRecordRepository::GetWhereNeverExpires()
|
||||
* CharacterStatsRecordRepository::GetWhereXAndY()
|
||||
* CharacterStatsRecordRepository::DeleteWhereXAndY()
|
||||
*
|
||||
* Most of the above could be covered by base methods, but if you as a developer
|
||||
* find yourself re-using logic for other parts of the code, its best to just make a
|
||||
* method that can be re-used easily elsewhere especially if it can use a base repository
|
||||
* method and encapsulate filters there
|
||||
*/
|
||||
|
||||
// Custom extended repository methods here
|
||||
|
||||
};
|
||||
|
||||
#endif //EQEMU_CHARACTER_STATS_RECORD_REPOSITORY_H
|
||||
@@ -47,17 +47,21 @@ public:
|
||||
static int UpdateRaidMarkedNPC(
|
||||
Database& db,
|
||||
int32_t raid_id,
|
||||
uint8_t marked_npc_number,
|
||||
uint8_t value
|
||||
uint32_t marked_npc_entity_id,
|
||||
uint32_t marked_npc_zone_id,
|
||||
uint32_t marked_npc_instance_id,
|
||||
uint32_t slot_number
|
||||
) {
|
||||
auto results = db.QueryDatabase(
|
||||
fmt::format(
|
||||
"UPDATE `{}` SET `marked_npc_{}` = '{}' WHERE raidid = '{}';",
|
||||
"UPDATE `{0}` SET `marked_npc_{4}_entity_id` = '{1}',`marked_npc_{4}_zone_id` = '{2}',`marked_npc_{4}_instance_id` = '{3}' WHERE raidid = '{5}';",
|
||||
TableName(),
|
||||
marked_npc_number,
|
||||
value,
|
||||
marked_npc_entity_id,
|
||||
marked_npc_zone_id,
|
||||
marked_npc_instance_id,
|
||||
slot_number,
|
||||
raid_id
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
return results.Success() ? results.RowsAffected() : 0;
|
||||
|
||||
+9
-3
@@ -58,6 +58,7 @@ RULE_REAL(Character, ExpMultiplier, 0.5, "If greater than 0, the experience gain
|
||||
RULE_REAL(Character, AAExpMultiplier, 0.5, "If greater than 0, the AA experience gained is multiplied by this value. ")
|
||||
RULE_REAL(Character, GroupExpMultiplier, 0.5, "The experience in a group is multiplied by this value in addition to the group multiplier. The group multiplier is: 2 members=x 1.2, 3=x1.4, 4=x1.6, 5=x1.8, 6=x2.16")
|
||||
RULE_REAL(Character, RaidExpMultiplier, 0.2, "The experience gained in raids is multiplied by (1-RaidExpMultiplier) ")
|
||||
RULE_REAL(Character, FinalRaidExpMultiplier, 1.0, "Multiplies all raid experience by this value. Default: 1.0")
|
||||
RULE_BOOL(Character, UseXPConScaling, true, "When activated, the experience is modified depending on the difference between player level and NPC level. The values from the rules GreenModifier to RedModifier are used")
|
||||
RULE_INT(Character, ShowExpValues, 0, "Show experience values. 0=normal, 1=show raw experience values, 2=show raw experience values and percent")
|
||||
RULE_INT(Character, GreenModifier, 20, "The experience obtained for green con mobs is multiplied by value/100")
|
||||
@@ -256,6 +257,7 @@ RULE_REAL(Pets, AttackCommandRange, 150, "Range at which a pet will respond to a
|
||||
RULE_BOOL(Pets, UnTargetableSwarmPet, false, "Setting whether swarm pets should be targetable")
|
||||
RULE_REAL(Pets, PetPowerLevelCap, 10, "Maximum number of levels a player pet can go up with pet power")
|
||||
RULE_BOOL(Pets, CanTakeNoDrop, false, "Setting whether anyone can give no-drop items to pets")
|
||||
RULE_BOOL(Pets, CanTakeQuestItems, true, "Setting whether anyone can give quest items to pets")
|
||||
RULE_BOOL(Pets, LivelikeBreakCharmOnInvis, true, "Default: true will break charm on any type of invis (hide/ivu/iva/etc) false will only break if the pet can not see you (ex. you have an undead pet and cast IVU")
|
||||
RULE_BOOL(Pets, ClientPetsUseOwnerNameInLastName, true, "Disable this to keep client pet's last names from being owner_name's pet")
|
||||
RULE_CATEGORY_END()
|
||||
@@ -287,7 +289,8 @@ RULE_BOOL(World, GMAccountIPList, false, "Check IP list against GM accounts. Thi
|
||||
RULE_INT(World, MinGMAntiHackStatus, 1, "Minimum status to check against AntiHack list")
|
||||
RULE_INT(World, SoFStartZoneID, -1, "Sets the Starting Zone for SoF Clients separate from Titanium Clients (-1 is disabled)")
|
||||
RULE_INT(World, TitaniumStartZoneID, -1, "Sets the Starting Zone for Titanium Clients (-1 is disabled). Replaces the old method")
|
||||
RULE_INT(World, ExpansionSettings, 16383, "Sets the expansion settings for the server, This is sent on login to world and affects client expansion settings. Defaults to all expansions enabled up to TSS, value is bitmask")
|
||||
RULE_INT(World, ExpansionSettings, 16383, "Sets the expansion settings bitmask for the server, This is sent on login to world and affects client expansion settings. Defaults to all expansions enabled up to TSS, value is bitmask")
|
||||
RULE_INT(World, CharacterSelectExpansionSettings, -1, "Sets the expansion settings bitmask for character select if you wish to override. -1 is off")
|
||||
RULE_BOOL(World, UseClientBasedExpansionSettings, true, "If true it will overrule World, ExpansionSettings and set someone's expansion based on the client they're using")
|
||||
RULE_INT(World, PVPSettings, 0, "Sets the PVP settings for the server. 1=Rallos Zek RuleSet, 2=Tallon/Vallon Zek Ruleset, 4=Sullon Zek Ruleset, 6=Discord Ruleset, anything above 6 is the Discord Ruleset without the no-drop restrictions removed. NOTE: edit IsAttackAllowed in Zone-table to accomodate for these rules")
|
||||
RULE_INT(World, PVPMinLevel, 0, "Minimum level to pvp")
|
||||
@@ -449,10 +452,12 @@ RULE_BOOL(Spells, TargetsTargetRequiresCombatRange, true, "Disable to remove com
|
||||
RULE_BOOL(Spells, NPCBuffLevelRestrictions, false, "Impose BuffLevelRestrictions on NPCs if true")
|
||||
RULE_INT(Spells, ResurrectionEffectBlock, 2, "0 = allow overwrites/rule disabled. If set to 1 = Block all buffs that would overwrite Resurrection Effects. If set to 2 = Will not overwrite Resurrection Effects, instead moves new buff to an empty slot if available. Default is 2.")
|
||||
RULE_BOOL(Spells, WaterMatchRequiredForLoS, true, "Enable/Disable the requirement of both the attacker/victim being both in or out of water for spells LoS to pass.")
|
||||
RULE_INT(Spells, WizardCritMinimumRandomRatio, 20, "The minimum value for the random range which Wizards and Caster DPS Mercs innately have for spell crit ratio. Set to 20 for vanilla values.")
|
||||
RULE_INT(Spells, WizardCritMaximumRandomRatio, 70, "The maximum value for the random range which Wizards and Caster DPS Mercs innately have for spell crit ratio. Set to 70 for vanilla values.")
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
RULE_CATEGORY(Combat)
|
||||
RULE_REAL(Combat, AERampageSafeZone, 0.018, "max hit ae ramp reduction range")
|
||||
RULE_REAL(Combat, AERampageMaxDistance, 70, "Max AERampage range (% of max combat distance)")
|
||||
RULE_INT(Combat, PetBaseCritChance, 0, "Pet base crit chance")
|
||||
RULE_INT(Combat, NPCBashKickLevel, 6, "The level that NPCcan KICK/BASH")
|
||||
RULE_INT(Combat, MeleeCritDifficulty, 8900, "Value against which is rolled to check if a melee crit is triggered. Lower is easier")
|
||||
@@ -540,6 +545,7 @@ RULE_INT(NPC, LastFightingDelayMovingMin, 10000, "Minimum time before mob goes h
|
||||
RULE_INT(NPC, LastFightingDelayMovingMax, 20000, "Maximum time before mob goes home after all aggro loss (milliseconds)")
|
||||
RULE_BOOL(NPC, SmartLastFightingDelayMoving, true, "When true, mobs that started going home previously will do so again immediately if still on FD hate list")
|
||||
RULE_BOOL(NPC, ReturnNonQuestNoDropItems, false, "Returns NO DROP items on NPC that don't have an EVENT_TRADE sub in their script")
|
||||
RULE_BOOL(NPC, ReturnQuestItemsFromNonQuestNPCs, false, "Returns Quest items traded to NPCs that are not flagged as a Quest NPC")
|
||||
RULE_INT(NPC, StartEnrageValue, 9, " Percentage HP that an NPC will begin to enrage")
|
||||
RULE_BOOL(NPC, LiveLikeEnrage, false, "If set to true then only player controlled pets will enrage")
|
||||
RULE_BOOL(NPC, EnableMeritBasedFaction, false, "If set to true, faction will be given in the same way as experience (solo/group/raid)")
|
||||
@@ -619,7 +625,7 @@ RULE_BOOL(Bots, FinishBuffing, false, "Allow for buffs to complete even if the b
|
||||
RULE_BOOL(Bots, GroupBuffing, false, "Bots will cast single target buffs as group buffs, default is false for single. Does not make single target buffs work for MGB")
|
||||
RULE_INT(Bots, HealRotationMaxMembers, 24, "Maximum number of heal rotation members")
|
||||
RULE_INT(Bots, HealRotationMaxTargets, 12, "Maximum number of heal rotation targets")
|
||||
RULE_REAL(Bots, ManaRegen, 2.0, "Adjust mana regen for bots, 1 is fast and higher numbers slow it down 3 is about the same as players")
|
||||
RULE_REAL(Bots, ManaRegen, 2.0, "Adjust mana regen. Acts as a final multiplier, stacks with Rule Character:ManaRegenMultiplier.")
|
||||
RULE_BOOL(Bots, PreferNoManaCommandSpells, true, "Give sorting priority to newer no-mana spells (i.e., 'Bind Affinity')")
|
||||
RULE_BOOL(Bots, QuestableSpawnLimit, false, "Optional quest method to manage bot spawn limits using the quest_globals name bot_spawn_limit, see: /bazaar/Aediles_Thrall.pl")
|
||||
RULE_INT(Bots, SpawnLimit, 71, "Number of bots a character can have spawned at one time, You + 71 bots is a 12 group pseudo-raid")
|
||||
|
||||
@@ -249,6 +249,7 @@
|
||||
#define ServerOP_ReloadZonePoints 0x4122
|
||||
#define ServerOP_ReloadDzTemplates 0x4123
|
||||
#define ServerOP_ReloadZoneData 0x4124
|
||||
#define ServerOP_ReloadDataBucketsCache 0x4125
|
||||
|
||||
#define ServerOP_CZDialogueWindow 0x4500
|
||||
#define ServerOP_CZLDoNUpdate 0x4501
|
||||
|
||||
+15
-15
@@ -376,7 +376,7 @@ std::string Strings::Money(uint64 platinum, uint64 gold, uint64 silver, uint64 c
|
||||
std::string money_string = "Unknown";
|
||||
if (copper && silver && gold && platinum) { // CSGP
|
||||
money_string = fmt::format(
|
||||
"{} Platinum, {} Gold, {} Silver, and {} Copper",
|
||||
"{} platinum, {} gold, {} silver, and {} copper",
|
||||
Strings::Commify(std::to_string(platinum)),
|
||||
Strings::Commify(std::to_string(gold)),
|
||||
Strings::Commify(std::to_string(silver)),
|
||||
@@ -385,7 +385,7 @@ std::string Strings::Money(uint64 platinum, uint64 gold, uint64 silver, uint64 c
|
||||
}
|
||||
else if (copper && silver && !gold && platinum) { // CSP
|
||||
money_string = fmt::format(
|
||||
"{} Platinum, {} Silver, and {} Copper",
|
||||
"{} platinum, {} silver, and {} copper",
|
||||
Strings::Commify(std::to_string(platinum)),
|
||||
Strings::Commify(std::to_string(silver)),
|
||||
Strings::Commify(std::to_string(copper))
|
||||
@@ -393,7 +393,7 @@ std::string Strings::Money(uint64 platinum, uint64 gold, uint64 silver, uint64 c
|
||||
}
|
||||
else if (copper && silver && gold && !platinum) { // CSG
|
||||
money_string = fmt::format(
|
||||
"{} Gold, {} Silver, and {} Copper",
|
||||
"{} gold, {} silver, and {} copper",
|
||||
Strings::Commify(std::to_string(gold)),
|
||||
Strings::Commify(std::to_string(silver)),
|
||||
Strings::Commify(std::to_string(copper))
|
||||
@@ -401,21 +401,21 @@ std::string Strings::Money(uint64 platinum, uint64 gold, uint64 silver, uint64 c
|
||||
}
|
||||
else if (copper && !silver && !gold && platinum) { // CP
|
||||
money_string = fmt::format(
|
||||
"{} Platinum and {} Copper",
|
||||
"{} platinum and {} copper",
|
||||
Strings::Commify(std::to_string(platinum)),
|
||||
Strings::Commify(std::to_string(copper))
|
||||
);
|
||||
}
|
||||
else if (copper && silver && !gold && !platinum) { // CS
|
||||
money_string = fmt::format(
|
||||
"{} Silver and {} Copper",
|
||||
"{} silver and {} copper",
|
||||
Strings::Commify(std::to_string(silver)),
|
||||
Strings::Commify(std::to_string(copper))
|
||||
);
|
||||
}
|
||||
else if (!copper && silver && gold && platinum) { // SGP
|
||||
money_string = fmt::format(
|
||||
"{} Platinum, {} Gold, and {} Silver",
|
||||
"{} platinum, {} gold, and {} silver",
|
||||
Strings::Commify(std::to_string(platinum)),
|
||||
Strings::Commify(std::to_string(gold)),
|
||||
Strings::Commify(std::to_string(silver))
|
||||
@@ -423,21 +423,21 @@ std::string Strings::Money(uint64 platinum, uint64 gold, uint64 silver, uint64 c
|
||||
}
|
||||
else if (!copper && silver && !gold && platinum) { // SP
|
||||
money_string = fmt::format(
|
||||
"{} Platinum and {} Silver",
|
||||
"{} platinum and {} silver",
|
||||
Strings::Commify(std::to_string(platinum)),
|
||||
Strings::Commify(std::to_string(silver))
|
||||
);
|
||||
}
|
||||
else if (!copper && silver && gold && !platinum) { // SG
|
||||
money_string = fmt::format(
|
||||
"{} Gold and {} Silver",
|
||||
"{} gold and {} silver",
|
||||
Strings::Commify(std::to_string(gold)),
|
||||
Strings::Commify(std::to_string(silver))
|
||||
);
|
||||
}
|
||||
else if (copper && !silver && gold && platinum) { // CGP
|
||||
money_string = fmt::format(
|
||||
"{} Platinum, {} Gold, and {} Copper",
|
||||
"{} platinum, {} gold, and {} copper",
|
||||
Strings::Commify(std::to_string(platinum)),
|
||||
Strings::Commify(std::to_string(gold)),
|
||||
Strings::Commify(std::to_string(copper))
|
||||
@@ -445,39 +445,39 @@ std::string Strings::Money(uint64 platinum, uint64 gold, uint64 silver, uint64 c
|
||||
}
|
||||
else if (copper && !silver && gold && !platinum) { // CG
|
||||
money_string = fmt::format(
|
||||
"{} Gold and {} Copper",
|
||||
"{} gold and {} copper",
|
||||
Strings::Commify(std::to_string(gold)),
|
||||
Strings::Commify(std::to_string(copper))
|
||||
);
|
||||
}
|
||||
else if (!copper && !silver && gold && platinum) { // GP
|
||||
money_string = fmt::format(
|
||||
"{} Platinum and {} Gold",
|
||||
"{} platinum and {} gold",
|
||||
Strings::Commify(std::to_string(platinum)),
|
||||
Strings::Commify(std::to_string(gold))
|
||||
);
|
||||
}
|
||||
else if (!copper && !silver && !gold && platinum) { // P
|
||||
money_string = fmt::format(
|
||||
"{} Platinum",
|
||||
"{} platinum",
|
||||
Strings::Commify(std::to_string(platinum))
|
||||
);
|
||||
}
|
||||
else if (!copper && !silver && gold && !platinum) { // G
|
||||
money_string = fmt::format(
|
||||
"{} Gold",
|
||||
"{} gold",
|
||||
Strings::Commify(std::to_string(gold))
|
||||
);
|
||||
}
|
||||
else if (!copper && silver && !gold && !platinum) { // S
|
||||
money_string = fmt::format(
|
||||
"{} Silver",
|
||||
"{} silver",
|
||||
Strings::Commify(std::to_string(silver))
|
||||
);
|
||||
}
|
||||
else if (copper && !silver && !gold && !platinum) { // C
|
||||
money_string = fmt::format(
|
||||
"{} Copper",
|
||||
"{} copper",
|
||||
Strings::Commify(std::to_string(copper))
|
||||
);
|
||||
}
|
||||
|
||||
+2
-2
@@ -25,7 +25,7 @@
|
||||
|
||||
// Build variables
|
||||
// these get injected during the build pipeline
|
||||
#define CURRENT_VERSION "22.22.0-dev" // always append -dev to the current version for custom-builds
|
||||
#define CURRENT_VERSION "22.25.0-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__
|
||||
@@ -42,7 +42,7 @@
|
||||
* Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
|
||||
*/
|
||||
|
||||
#define CURRENT_BINARY_DATABASE_VERSION 9233
|
||||
#define CURRENT_BINARY_DATABASE_VERSION 9235
|
||||
|
||||
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9039
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "eqemu-server",
|
||||
"version": "22.22.0",
|
||||
"version": "22.25.0",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/EQEmu/Server.git"
|
||||
|
||||
@@ -44,7 +44,7 @@ echo "Generating [create_*] table exports..."
|
||||
bash -c "${world_bin} database:dump --login-tables --table-structure-only --dump-output-to-console | sed 's/ AUTO_INCREMENT=[0-9]*\b//g' > ${dump_path}create_tables_login.sql"
|
||||
bash -c "${world_bin} database:dump --player-tables --table-structure-only --dump-output-to-console | sed 's/ AUTO_INCREMENT=[0-9]*\b//g' > ${dump_path}create_tables_player.sql"
|
||||
bash -c "${world_bin} database:dump --state-tables --table-structure-only --dump-output-to-console | sed 's/ AUTO_INCREMENT=[0-9]*\b//g' > ${dump_path}create_tables_state.sql"
|
||||
echo 'REPLACE INTO `instance_list` VALUES (1,25,1,1,0,0,1),(2,25,2,1,0,0,1),(3,151,1,1,0,0,1),(4,114,1,1,0,0,1),(5,344,1,1,0,0,1),(6,202,0,1,0,0,1);' >> "${dump_path}create_tables_state.sql"
|
||||
bash -c "${world_bin} database:dump --static-instance-data --dump-output-to-console >> ${dump_path}create_tables_state.sql"
|
||||
bash -c "${world_bin} database:dump --query-serv-tables --table-structure-only --dump-output-to-console | sed 's/ AUTO_INCREMENT=[0-9]*\b//g' > ${dump_path}create_tables_queryserv.sql"
|
||||
|
||||
# with content
|
||||
|
||||
@@ -15,6 +15,7 @@ void WorldserverCLI::DatabaseDump(int argc, char **argv, argh::parser &cmd, std:
|
||||
"--state-tables",
|
||||
"--system-tables",
|
||||
"--query-serv-tables",
|
||||
"--static-instance-data",
|
||||
"--table-structure-only",
|
||||
"--table-lock",
|
||||
"--dump-path=",
|
||||
@@ -51,6 +52,7 @@ void WorldserverCLI::DatabaseDump(int argc, char **argv, argh::parser &cmd, std:
|
||||
s->SetDumpWithCompression(cmd[{"--compress"}]);
|
||||
s->SetDumpOutputToConsole(cmd[{"--dump-output-to-console"}]);
|
||||
s->SetDumpDropTableSyntaxOnly(cmd[{"--drop-table-syntax-only"}]);
|
||||
s->SetDumpStaticInstanceData(cmd[{"--static-instance-data"}]);
|
||||
|
||||
s->DatabaseDump();
|
||||
}
|
||||
|
||||
+5
-2
@@ -208,11 +208,14 @@ void Client::SendExpansionInfo() {
|
||||
auto outapp = new EQApplicationPacket(OP_ExpansionInfo, sizeof(ExpansionInfo_Struct));
|
||||
ExpansionInfo_Struct *eis = (ExpansionInfo_Struct*)outapp->pBuffer;
|
||||
|
||||
if (RuleB(World, UseClientBasedExpansionSettings)) {
|
||||
if (RuleI(World, CharacterSelectExpansionSettings) != -1) {
|
||||
eis->Expansions = RuleI(World, CharacterSelectExpansionSettings);
|
||||
}
|
||||
else if (RuleB(World, UseClientBasedExpansionSettings)) {
|
||||
eis->Expansions = EQ::expansions::ConvertClientVersionToExpansionsMask(eqs->ClientVersion());
|
||||
}
|
||||
else {
|
||||
eis->Expansions = (RuleI(World, ExpansionSettings) & EQ::expansions::ConvertClientVersionToExpansionsMask(eqs->ClientVersion()));
|
||||
eis->Expansions = RuleI(World, ExpansionSettings);
|
||||
}
|
||||
|
||||
QueuePacket(outapp);
|
||||
|
||||
@@ -138,6 +138,7 @@ std::vector<Reload> reload_types = {
|
||||
Reload{.command = "alternate_currencies", .opcode = ServerOP_ReloadAlternateCurrencies, .desc = "Alternate Currencies"},
|
||||
Reload{.command = "blocked_spells", .opcode = ServerOP_ReloadBlockedSpells, .desc = "Blocked Spells"},
|
||||
Reload{.command = "commands", .opcode = ServerOP_ReloadCommands, .desc = "Commands"},
|
||||
Reload{.command = "data_buckets_cache", .opcode = ServerOP_ReloadDataBucketsCache, .desc = "Data Buckets Cache"},
|
||||
Reload{.command = "doors", .opcode = ServerOP_ReloadDoors, .desc = "Doors"},
|
||||
Reload{.command = "dztemplates", .opcode = ServerOP_ReloadDzTemplates, .desc = "Dynamic Zone Templates"},
|
||||
Reload{.command = "ground_spawns", .opcode = ServerOP_ReloadGroundSpawns, .desc = "Ground Spawns"},
|
||||
|
||||
+58
-8
@@ -795,11 +795,29 @@ void ZoneServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) {
|
||||
client = client_list.FindCharacter(ztz->name);
|
||||
}
|
||||
|
||||
LogInfo("ZoneToZone request for [{}] current zone [{}] req zone [{}]", ztz->name, ztz->current_zone_id, ztz->requested_zone_id);
|
||||
LogZoning(
|
||||
"ZoneToZone request for client [{}] guild_id [{}] requested_zone [{}] requested_zone_id [{}] requested_instance_id [{}] current_zone [{}] current_zone_id [{}] current_instance_id [{}] response [{}] admin [{}] ignorerestrictions [{}]",
|
||||
ztz->name,
|
||||
ztz->guild_id,
|
||||
ZoneName(ztz->requested_zone_id),
|
||||
ztz->requested_zone_id,
|
||||
ztz->requested_instance_id,
|
||||
ZoneName(ztz->current_zone_id),
|
||||
ztz->current_zone_id,
|
||||
ztz->current_instance_id,
|
||||
ztz->response,
|
||||
ztz->admin,
|
||||
ztz->ignorerestrictions
|
||||
);
|
||||
|
||||
/* This is a request from the egress zone */
|
||||
if (GetZoneID() == ztz->current_zone_id && GetInstanceID() == ztz->current_instance_id) {
|
||||
LogInfo("Processing ZTZ for egress from zone for client [{}]", ztz->name);
|
||||
LogZoning(
|
||||
"ZoneToZone request for client [{}] for egress from zone [{}]",
|
||||
ztz->name,
|
||||
ZoneName(ztz->current_zone_id),
|
||||
ztz->current_zone_id
|
||||
);
|
||||
|
||||
if (
|
||||
ztz->admin < AccountStatus::QuestTroupe &&
|
||||
@@ -807,6 +825,14 @@ void ZoneServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) {
|
||||
zoneserver_list.IsZoneLocked(ztz->requested_zone_id)
|
||||
) {
|
||||
ztz->response = 0;
|
||||
|
||||
LogZoning(
|
||||
"ZoneToZone request for client [{}] for egress from zone [{}] denied, zone is locked",
|
||||
ztz->name,
|
||||
ZoneName(ztz->current_zone_id),
|
||||
ztz->current_zone_id
|
||||
);
|
||||
|
||||
SendPacket(pack);
|
||||
break;
|
||||
}
|
||||
@@ -818,12 +844,25 @@ void ZoneServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) {
|
||||
);
|
||||
|
||||
if (ingress_server) {
|
||||
LogInfo("Found a zone already booted for [{}]", ztz->name);
|
||||
LogZoning(
|
||||
"Found a zone already booted for ZoneToZone for client [{}] for ingress_server from zone [{}] found booted zone",
|
||||
ztz->name,
|
||||
ZoneName(ztz->current_zone_id),
|
||||
ztz->current_zone_id
|
||||
);
|
||||
|
||||
ztz->response = 1;
|
||||
} else {
|
||||
int server_id;
|
||||
if ((server_id = zoneserver_list.TriggerBootup(ztz->requested_zone_id, ztz->requested_instance_id))) {
|
||||
LogInfo("Successfully booted a zone for [{}]", ztz->name);
|
||||
LogZoning(
|
||||
"ZoneToZone successfully booted a zone for character [{}] zone [{}] ({}) instance [{}] ({})",
|
||||
ztz->name,
|
||||
ZoneName(ztz->requested_zone_id),
|
||||
ztz->requested_zone_id,
|
||||
ztz->requested_instance_id,
|
||||
server_id
|
||||
);
|
||||
ztz->response = 1;
|
||||
ingress_server = zoneserver_list.FindByID(server_id);
|
||||
} else {
|
||||
@@ -841,8 +880,8 @@ void ZoneServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) {
|
||||
ingress_server->SendPacket(pack); // inform target server
|
||||
}
|
||||
} else {
|
||||
LogInfo(
|
||||
"Processing ZTZ for ingress to zone for client [{}] instance_id [{}] zone_id [{}]",
|
||||
LogZoning(
|
||||
"Processing ZTZ for egress to zone for client [{}] instance_id [{}] zone_id [{}]",
|
||||
ztz->name,
|
||||
ztz->current_instance_id,
|
||||
ztz->current_zone_id
|
||||
@@ -854,7 +893,13 @@ void ZoneServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) {
|
||||
);
|
||||
|
||||
if (egress_server) {
|
||||
LogInfo("Found egress server, forwarding client");
|
||||
LogZoning(
|
||||
"Found egress server_id [{}] zone_id [{}] zone_name [{}] instance_id [{}], forwarding client",
|
||||
egress_server->GetID(),
|
||||
egress_server->GetZoneID(),
|
||||
egress_server->GetZoneName(),
|
||||
egress_server->GetInstanceID()
|
||||
);
|
||||
egress_server->SendPacket(pack);
|
||||
}
|
||||
}
|
||||
@@ -1343,13 +1388,13 @@ void ZoneServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) {
|
||||
case ServerOP_ReloadBlockedSpells:
|
||||
case ServerOP_ReloadCommands:
|
||||
case ServerOP_ReloadDoors:
|
||||
case ServerOP_ReloadDataBucketsCache:
|
||||
case ServerOP_ReloadGroundSpawns:
|
||||
case ServerOP_ReloadLevelEXPMods:
|
||||
case ServerOP_ReloadMerchants:
|
||||
case ServerOP_ReloadNPCEmotes:
|
||||
case ServerOP_ReloadObjects:
|
||||
case ServerOP_ReloadPerlExportSettings:
|
||||
case ServerOP_ReloadRules:
|
||||
case ServerOP_ReloadStaticZoneData:
|
||||
case ServerOP_ReloadTitles:
|
||||
case ServerOP_ReloadTraps:
|
||||
@@ -1374,6 +1419,11 @@ void ZoneServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) {
|
||||
zoneserver_list.SendPacket(pack);
|
||||
break;
|
||||
}
|
||||
case ServerOP_ReloadRules: {
|
||||
zoneserver_list.SendPacket(pack);
|
||||
RuleManager::Instance()->LoadRules(&database, "default", true);
|
||||
break;
|
||||
}
|
||||
case ServerOP_ReloadContentFlags: {
|
||||
zoneserver_list.SendPacket(pack);
|
||||
content_service.SetExpansionContext()->ReloadContentFlags();
|
||||
|
||||
+1
-3
@@ -1701,9 +1701,7 @@ bool Mob::CanPurchaseAlternateAdvancementRank(AA::Rank *rank, bool check_price,
|
||||
}
|
||||
|
||||
void Zone::LoadAlternateAdvancement() {
|
||||
if(!content_db.LoadAlternateAdvancementAbilities(aa_abilities,
|
||||
aa_ranks))
|
||||
{
|
||||
if (!content_db.LoadAlternateAdvancementAbilities(aa_abilities, aa_ranks)) {
|
||||
aa_abilities.clear();
|
||||
aa_ranks.clear();
|
||||
LogInfo("Failed to load Alternate Advancement Data");
|
||||
|
||||
+19
-10
@@ -975,8 +975,7 @@ bool Mob::IsBeneficialAllowed(Mob *target)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Mob::CombatRange(Mob* other, float fixed_size_mod, bool aeRampage)
|
||||
{
|
||||
bool Mob::CombatRange(Mob* other, float fixed_size_mod, bool aeRampage, ExtraAttackOptions *opts) {
|
||||
if (!other) {
|
||||
return(false);
|
||||
}
|
||||
@@ -1071,18 +1070,28 @@ bool Mob::CombatRange(Mob* other, float fixed_size_mod, bool aeRampage)
|
||||
SetPseudoRoot(false);
|
||||
}
|
||||
}
|
||||
|
||||
if (aeRampage) {
|
||||
float multiplyer = GetSize() * RuleR(Combat, AERampageSafeZone);
|
||||
float ramp_range = (size_mod * multiplyer);
|
||||
if (_DistNoRoot <= ramp_range) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
float aeramp_size = RuleR(Combat, AERampageMaxDistance);
|
||||
|
||||
if (opts) {
|
||||
if (opts->range_percent > 0) {
|
||||
aeramp_size = opts->range_percent;
|
||||
}
|
||||
}
|
||||
|
||||
if (aeramp_size <= 0) {
|
||||
aeramp_size = 0.90;
|
||||
} else {
|
||||
aeramp_size /= 100;
|
||||
}
|
||||
|
||||
float ramp_range = size_mod * aeramp_size;
|
||||
|
||||
return _DistNoRoot <= ramp_range;
|
||||
}
|
||||
|
||||
if (_DistNoRoot <= size_mod)
|
||||
{
|
||||
if (_DistNoRoot <= size_mod) {
|
||||
//A hack to kill an exploit till we get something better.
|
||||
if (flymode != GravityBehavior::Flying && _zDist > 500 && !CheckLastLosState()) {
|
||||
return false;
|
||||
|
||||
+30
-12
@@ -4230,7 +4230,7 @@ void Mob::CommonDamage(Mob* attacker, int64 &damage, const uint16 spell_id, cons
|
||||
//attacker is a pet, let pet owners see their pet's damage
|
||||
Mob* owner = attacker->GetOwner();
|
||||
if (owner && owner->IsClient()) {
|
||||
if ((IsValidSpell(spell_id) || (FromDamageShield)) && damage > 0) {
|
||||
if (FromDamageShield && damage > 0) {
|
||||
//special crap for spell damage, looks hackish to me
|
||||
char val1[20] = { 0 };
|
||||
owner->MessageString(Chat::NonMelee, OTHER_HIT_NONMELEE, GetCleanName(), ConvertArray(damage, val1));
|
||||
@@ -4249,7 +4249,15 @@ void Mob::CommonDamage(Mob* attacker, int64 &damage, const uint16 spell_id, cons
|
||||
filter = FilterPetMisses;
|
||||
|
||||
if (!FromDamageShield)
|
||||
owner->CastToClient()->QueuePacket(outapp, true, CLIENT_CONNECTED, filter);
|
||||
entity_list.QueueCloseClients(
|
||||
this, /* Sender */
|
||||
outapp, /* packet */
|
||||
false, /* Skip Sender */
|
||||
((IsValidSpell(spell_id)) ? RuleI(Range, SpellMessages) : RuleI(Range, DamageMessages)),
|
||||
0, /* don't skip anyone on spell */
|
||||
true, /* Packet ACK */
|
||||
filter /* eqFilterType filter */
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4351,16 +4359,21 @@ void Mob::CommonDamage(Mob* attacker, int64 &damage, const uint16 spell_id, cons
|
||||
CastToClient()->QueuePacket(outapp);
|
||||
}
|
||||
|
||||
// Otherwise, send normal spell or melee message to observers.
|
||||
entity_list.QueueCloseClients(
|
||||
this, /* Sender */
|
||||
outapp, /* packet */
|
||||
true, /* Skip Sender */
|
||||
range, /* distance packet travels at the speed of sound */
|
||||
(IsValidSpell(spell_id) && skill_used != EQ::skills::SkillTigerClaw) ? 0 : skip,
|
||||
true, /* Packet ACK */
|
||||
filter /* eqFilterType filter */
|
||||
);
|
||||
// Send normal message to observers
|
||||
// Exclude damage done by client pets as that's handled
|
||||
// elsewhere using proper "my pet damage filter"
|
||||
Mob *owner = attacker->GetOwner();
|
||||
if (!owner || (owner && !owner->IsClient())) {
|
||||
entity_list.QueueCloseClients(
|
||||
this, /* Sender */
|
||||
outapp, /* packet */
|
||||
true, /* Skip Sender */
|
||||
range, /* distance packet travels at the speed of sound */
|
||||
(IsValidSpell(spell_id) && skill_used != EQ::skills::SkillTigerClaw) ? 0 : skip,
|
||||
true, /* Packet ACK */
|
||||
filter /* eqFilterType filter */
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6458,3 +6471,8 @@ int64 Mob::GetManaRegen() const
|
||||
{
|
||||
return mana_regen;
|
||||
}
|
||||
|
||||
int64 Mob::GetEnduranceRegen() const
|
||||
{
|
||||
return 0; // not implemented
|
||||
}
|
||||
|
||||
+65
-96
@@ -119,7 +119,15 @@ 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)
|
||||
Bot::Bot(
|
||||
uint32 botID,
|
||||
uint32 botOwnerCharacterID,
|
||||
uint32 botSpellsID,
|
||||
double totalPlayTime,
|
||||
uint32 lastZoneId,
|
||||
NPCType *npcTypeData,
|
||||
int32 expansion_bitmask
|
||||
)
|
||||
: NPC(npcTypeData, nullptr, glm::vec4(), Ground, false), rest_timer(1), ping_timer(1)
|
||||
{
|
||||
GiveNPCTypeData(npcTypeData);
|
||||
@@ -161,6 +169,7 @@ Bot::Bot(uint32 botID, uint32 botOwnerCharacterID, uint32 botSpellsID, double to
|
||||
RestRegenHP = 0;
|
||||
RestRegenMana = 0;
|
||||
RestRegenEndurance = 0;
|
||||
m_expansion_bitmask = expansion_bitmask;
|
||||
SetBotID(botID);
|
||||
SetBotSpellID(botSpellsID);
|
||||
SetSpawnStatus(false);
|
||||
@@ -268,26 +277,48 @@ Bot::Bot(uint32 botID, uint32 botOwnerCharacterID, uint32 botSpellsID, double to
|
||||
case SE_IllusionCopy:
|
||||
case SE_Illusion: {
|
||||
if (spell.base_value[x1] == -1) {
|
||||
if (gender == 1)
|
||||
gender = 0;
|
||||
else if (gender == 0)
|
||||
gender = 1;
|
||||
SendIllusionPacket(GetRace(), gender, 0xFF, 0xFF);
|
||||
}
|
||||
else if (spell.base_value[x1] == -2) // WTF IS THIS
|
||||
if (gender == FEMALE) {
|
||||
gender = MALE;
|
||||
} else if (gender == MALE) {
|
||||
gender = FEMALE;
|
||||
}
|
||||
|
||||
SendIllusionPacket(
|
||||
AppearanceStruct{
|
||||
.gender_id = gender,
|
||||
.race_id = GetRace(),
|
||||
}
|
||||
);
|
||||
} else if (spell.base_value[x1] == -2) // WTF IS THIS
|
||||
{
|
||||
if (GetRace() == IKSAR || GetRace() == VAHSHIR || GetRace() <= GNOME) {
|
||||
SendIllusionPacket(GetRace(), GetGender(), spell.limit_value[x1], spell.max_value[x1]);
|
||||
SendIllusionPacket(
|
||||
AppearanceStruct{
|
||||
.gender_id = GetGender(),
|
||||
.helmet_texture = static_cast<uint8>(spell.max_value[x1]),
|
||||
.race_id = GetRace(),
|
||||
.texture = static_cast<uint8>(spell.limit_value[x1]),
|
||||
}
|
||||
);
|
||||
}
|
||||
} else if (spell.max_value[x1] > 0) {
|
||||
SendIllusionPacket(
|
||||
AppearanceStruct{
|
||||
.helmet_texture = static_cast<uint8>(spell.max_value[x1]),
|
||||
.race_id = static_cast<uint16>(spell.base_value[x1]),
|
||||
.texture = static_cast<uint8>(spell.limit_value[x1]),
|
||||
}
|
||||
);
|
||||
} else {
|
||||
SendIllusionPacket(
|
||||
AppearanceStruct{
|
||||
.helmet_texture = static_cast<uint8>(spell.max_value[x1]),
|
||||
.race_id = static_cast<uint16>(spell.base_value[x1]),
|
||||
.texture = static_cast<uint8>(spell.limit_value[x1]),
|
||||
}
|
||||
);
|
||||
}
|
||||
else if (spell.max_value[x1] > 0)
|
||||
{
|
||||
SendIllusionPacket(spell.base_value[x1], 0xFF, spell.limit_value[x1], spell.max_value[x1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
SendIllusionPacket(spell.base_value[x1], 0xFF, 0xFF, 0xFF);
|
||||
}
|
||||
|
||||
switch (spell.base_value[x1]) {
|
||||
case OGRE:
|
||||
SendAppearancePacket(AT_Size, 9);
|
||||
@@ -3306,16 +3337,23 @@ bool Bot::Spawn(Client* botCharacterOwner) {
|
||||
|
||||
if (auto raid = entity_list.GetRaidByBotName(GetName())) {
|
||||
// Safety Check to confirm we have a valid raid
|
||||
if (raid->IsRaidMember(GetBotOwner()->CastToClient())) {
|
||||
if (!raid->IsRaidMember(GetBotOwner()->GetName())) {
|
||||
Bot::RemoveBotFromRaid(this);
|
||||
} else {
|
||||
raid->LearnMembers();
|
||||
SetRaidGrouped(true);
|
||||
raid->LearnMembers();
|
||||
raid->VerifyRaid();
|
||||
}
|
||||
}
|
||||
else if (auto group = entity_list.GetGroupByMobName(GetName())) {
|
||||
group->LearnMembers();
|
||||
SetGrouped(true);
|
||||
// Safety Check to confirm we have a valid group
|
||||
if (!group->IsGroupMember(GetBotOwner()->GetName())) {
|
||||
Bot::RemoveBotFromGroup(this, group);
|
||||
} else {
|
||||
SetGrouped(true);
|
||||
group->LearnMembers();
|
||||
group->VerifyGroup();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -4512,10 +4550,9 @@ void Bot::PerformTradeWithClient(int16 begin_slot_id, int16 end_slot_id, Client*
|
||||
}
|
||||
|
||||
bool Bot::Death(Mob *killerMob, int64 damage, uint16 spell_id, EQ::skills::SkillType attack_skill) {
|
||||
if (!NPC::Death(killerMob, damage, spell_id, attack_skill))
|
||||
if (!NPC::Death(killerMob, damage, spell_id, attack_skill)) {
|
||||
return false;
|
||||
|
||||
Save();
|
||||
}
|
||||
|
||||
Mob *my_owner = GetBotOwner();
|
||||
if (my_owner && my_owner->IsClient() && my_owner->CastToClient()->GetBotOption(Client::booDeathMarquee)) {
|
||||
@@ -4525,81 +4562,11 @@ bool Bot::Death(Mob *killerMob, int64 damage, uint16 spell_id, EQ::skills::Skill
|
||||
my_owner->CastToClient()->SendMarqueeMessage(Chat::White, 510, 0, 1000, 3000, StringFormat("%s has been slain", GetCleanName()));
|
||||
}
|
||||
|
||||
Mob *give_exp = hate_list.GetDamageTopOnHateList(this);
|
||||
Client *give_exp_client = nullptr;
|
||||
if (give_exp && give_exp->IsClient())
|
||||
give_exp_client = give_exp->CastToClient();
|
||||
|
||||
bool IsLdonTreasure = (GetClass() == LDON_TREASURE);
|
||||
const auto c = entity_list.GetCorpseByID(GetID());
|
||||
if (c) {
|
||||
c->Depop();
|
||||
}
|
||||
|
||||
if (HasRaid()) {
|
||||
if (auto raid = entity_list.GetRaidByBotName(GetName()); raid) {
|
||||
for (auto& m: raid->members) {
|
||||
if (strcmp(m.member_name, GetName()) == 0) {
|
||||
m.member = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (HasGroup()) {
|
||||
if (auto g = GetGroup()) {
|
||||
for (int i = 0; i < MAX_GROUP_MEMBERS; i++) {
|
||||
if (g->members[i]) {
|
||||
if (g->members[i] == this) {
|
||||
// If the leader dies, make the next bot the leader
|
||||
// and reset all bots followid
|
||||
if (g->IsLeader(g->members[i])) {
|
||||
if (g->members[i + 1]) {
|
||||
g->SetLeader(g->members[i + 1]);
|
||||
g->members[i + 1]->SetFollowID(g->members[i]->GetFollowID());
|
||||
for (int j = 0; j < MAX_GROUP_MEMBERS; j++) {
|
||||
if (g->members[j] && (g->members[j] != g->members[i + 1]))
|
||||
g->members[j]->SetFollowID(g->members[i + 1]->GetID());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// delete from group data
|
||||
RemoveBotFromGroup(this, g);
|
||||
//Make sure group still exists if it doesnt they were already updated in RemoveBotFromGroup
|
||||
g = GetGroup();
|
||||
if (!g)
|
||||
break;
|
||||
|
||||
// if group members exist below this one, move
|
||||
// them all up one slot in the group list
|
||||
int j = (i + 1);
|
||||
for (; j < MAX_GROUP_MEMBERS; j++) {
|
||||
if (g->members[j]) {
|
||||
g->members[j - 1] = g->members[j];
|
||||
strcpy(g->membername[j - 1], g->members[j]->GetCleanName());
|
||||
g->membername[j][0] = '\0';
|
||||
memset(g->membername[j], 0, 64);
|
||||
g->members[j] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// update the client group
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_GroupUpdate, sizeof(GroupJoin_Struct));
|
||||
GroupJoin_Struct* gu = (GroupJoin_Struct*) outapp->pBuffer;
|
||||
gu->action = groupActLeave;
|
||||
strcpy(gu->membername, GetCleanName());
|
||||
for (int k = 0; k < MAX_GROUP_MEMBERS; k++) {
|
||||
if (g->members[k] && g->members[k]->IsClient()) {
|
||||
g->members[k]->CastToClient()->QueuePacket(outapp);
|
||||
}
|
||||
}
|
||||
safe_delete(outapp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LeaveHealRotationMemberPool();
|
||||
|
||||
if ((GetPullingFlag() || GetReturningFlag()) && my_owner && my_owner->IsClient()) {
|
||||
@@ -4618,6 +4585,7 @@ bool Bot::Death(Mob *killerMob, int64 damage, uint16 spell_id, EQ::skills::Skill
|
||||
parse->EventBot(EVENT_DEATH_COMPLETE, this, killerMob, export_string, 0);
|
||||
}
|
||||
|
||||
Zone();
|
||||
entity_list.RemoveBot(GetID());
|
||||
|
||||
return true;
|
||||
@@ -5432,10 +5400,10 @@ void Bot::ProcessBotOwnerRefDelete(Mob* botOwner) {
|
||||
int64 Bot::CalcMaxMana() {
|
||||
switch(GetCasterClass()) {
|
||||
case 'I':
|
||||
max_mana = (GenerateBaseManaPoints() + itembonuses.Mana + spellbonuses.Mana + GroupLeadershipAAManaEnhancement());
|
||||
max_mana = (GenerateBaseManaPoints() + itembonuses.Mana + spellbonuses.Mana + aabonuses.Mana + GroupLeadershipAAManaEnhancement());
|
||||
max_mana += itembonuses.heroic_max_mana;
|
||||
case 'W': {
|
||||
max_mana = (GenerateBaseManaPoints() + itembonuses.Mana + spellbonuses.Mana + GroupLeadershipAAManaEnhancement());
|
||||
max_mana = (GenerateBaseManaPoints() + itembonuses.Mana + spellbonuses.Mana + aabonuses.Mana + GroupLeadershipAAManaEnhancement());
|
||||
max_mana += itembonuses.heroic_max_mana;
|
||||
break;
|
||||
}
|
||||
@@ -8202,6 +8170,7 @@ bool Bot::CheckDataBucket(std::string bucket_name, const std::string& bucket_val
|
||||
if (b.value.empty() && GetBotOwner()) {
|
||||
// fetch from owner
|
||||
k = GetBotOwner()->GetScopedBucketKeys();
|
||||
k.key = bucket_name;
|
||||
|
||||
b = DataBucket::GetData(k);
|
||||
if (b.value.empty()) {
|
||||
|
||||
+1
-1
@@ -130,7 +130,7 @@ public:
|
||||
|
||||
// Class Constructors
|
||||
Bot(NPCType *npcTypeData, Client* botOwner);
|
||||
Bot(uint32 botID, uint32 botOwnerCharacterID, uint32 botSpellsID, double totalPlayTime, uint32 lastZoneId, NPCType *npcTypeData);
|
||||
Bot(uint32 botID, uint32 botOwnerCharacterID, uint32 botSpellsID, double totalPlayTime, uint32 lastZoneId, NPCType *npcTypeData, int32 expansion_bitmask);
|
||||
|
||||
//abstract virtual override function implementations requird by base abstract class
|
||||
bool Death(Mob* killerMob, int64 damage, uint16 spell_id, EQ::skills::SkillType attack_skill) override;
|
||||
|
||||
+38
-37
@@ -63,6 +63,7 @@
|
||||
#include "water_map.h"
|
||||
#include "worldserver.h"
|
||||
#include "dialogue_window.h"
|
||||
#include "mob.h"
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
@@ -2098,7 +2099,6 @@ namespace ActionableBots
|
||||
ABT_Target,
|
||||
ABT_ByName,
|
||||
ABT_OwnerGroup,
|
||||
ABT_BotGroup,
|
||||
ABT_TargetGroup,
|
||||
ABT_NamesGroup,
|
||||
ABT_HealRotation,
|
||||
@@ -2439,7 +2439,6 @@ void bot_command_actionable(Client *c, const Seperator *sep)
|
||||
c->Message(Chat::White, "target - selects target as single bot .. use ^command [target] or imply by empty actionable argument");
|
||||
c->Message(Chat::White, "byname [name] - selects single bot by name");
|
||||
c->Message(Chat::White, "ownergroup - selects all bots in the owner's group");
|
||||
c->Message(Chat::White, "botgroup [name] - selects members of a bot-group by its name");
|
||||
c->Message(Chat::White, "targetgroup - selects all bots in target's group");
|
||||
c->Message(Chat::White, "namesgroup [name] - selects all bots in name's group");
|
||||
c->Message(Chat::White, "healrotation [name] - selects all member and target bots of a heal rotation where name is a member");
|
||||
@@ -2457,7 +2456,7 @@ void bot_command_aggressive(Client *c, const Seperator *sep)
|
||||
if (helper_spell_list_fail(c, local_list, BCEnum::SpT_Stance) || helper_command_alias_fail(c, "bot_command_aggressive", sep->arg[0], "aggressive"))
|
||||
return;
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
c->Message(Chat::White, "usage: %s ([actionable: target | byname | ownergroup | botgroup | targetgroup | namesgroup | healrotationtargets | spawned] ([actionable_name]))", sep->arg[0]);
|
||||
c->Message(Chat::White, "usage: %s ([actionable: target | byname | ownergroup | targetgroup | namesgroup | healrotationtargets | spawned] ([actionable_name]))", sep->arg[0]);
|
||||
helper_send_usage_required_bots(c, BCEnum::SpT_Stance);
|
||||
return;
|
||||
}
|
||||
@@ -2687,7 +2686,7 @@ void bot_command_attack(Client *c, const Seperator *sep)
|
||||
}
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
|
||||
c->Message(Chat::White, "usage: <enemy_target> %s [actionable: byname | ownergroup | botgroup | namesgroup | healrotation | default: spawned] ([actionable_name])", sep->arg[0]);
|
||||
c->Message(Chat::White, "usage: <enemy_target> %s [actionable: byname | ownergroup | namesgroup | healrotation | default: spawned] ([actionable_name])", sep->arg[0]);
|
||||
return;
|
||||
}
|
||||
const int ab_mask = ActionableBots::ABM_Type2;
|
||||
@@ -2944,7 +2943,7 @@ void bot_command_defensive(Client *c, const Seperator *sep)
|
||||
if (helper_spell_list_fail(c, local_list, BCEnum::SpT_Stance) || helper_command_alias_fail(c, "bot_command_defensive", sep->arg[0], "defensive"))
|
||||
return;
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
c->Message(Chat::White, "usage: %s ([actionable: target | byname | ownergroup | botgroup | targetgroup | namesgroup | healrotationtargets | spawned] ([actionable_name]))", sep->arg[0]);
|
||||
c->Message(Chat::White, "usage: %s ([actionable: target | byname | ownergroup | targetgroup | namesgroup | healrotationtargets | spawned] ([actionable_name]))", sep->arg[0]);
|
||||
helper_send_usage_required_bots(c, BCEnum::SpT_Stance);
|
||||
return;
|
||||
}
|
||||
@@ -3146,7 +3145,7 @@ void bot_command_follow(Client *c, const Seperator *sep)
|
||||
if (helper_command_alias_fail(c, "bot_command_follow", sep->arg[0], "follow"))
|
||||
return;
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
c->Message(Chat::White, "usage: (<friendly_target>) %s ([option: reset]) [actionable: byname | ownergroup | botgroup | namesgroup | healrotation | spawned] ([actionable_name])", sep->arg[0]);
|
||||
c->Message(Chat::White, "usage: (<friendly_target>) %s ([option: reset]) [actionable: byname | ownergroup | namesgroup | healrotation | spawned] ([actionable_name])", sep->arg[0]);
|
||||
c->Message(Chat::White, "usage: %s chain", sep->arg[0]);
|
||||
return;
|
||||
}
|
||||
@@ -3253,7 +3252,7 @@ void bot_command_guard(Client *c, const Seperator *sep)
|
||||
}
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
|
||||
c->Message(Chat::White, "usage: %s ([option: clear]) [actionable: target | byname | ownergroup | botgroup | namesgroup | healrotation | spawned] ([actionable_name])", sep->arg[0]);
|
||||
c->Message(Chat::White, "usage: %s ([option: clear]) [actionable: target | byname | ownergroup | namesgroup | healrotation | spawned] ([actionable_name])", sep->arg[0]);
|
||||
return;
|
||||
}
|
||||
const int ab_mask = (ActionableBots::ABM_Target | ActionableBots::ABM_Type2);
|
||||
@@ -3387,7 +3386,7 @@ void bot_command_hold(Client *c, const Seperator *sep)
|
||||
}
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
|
||||
c->Message(Chat::White, "usage: %s ([option: clear]) [actionable: target | byname | ownergroup | botgroup | namesgroup | healrotation | spawned] ([actionable_name])", sep->arg[0]);
|
||||
c->Message(Chat::White, "usage: %s ([option: clear]) [actionable: target | byname | ownergroup | namesgroup | healrotation | spawned] ([actionable_name])", sep->arg[0]);
|
||||
return;
|
||||
}
|
||||
const int ab_mask = (ActionableBots::ABM_Target | ActionableBots::ABM_Type2);
|
||||
@@ -4727,7 +4726,7 @@ void bot_command_taunt(Client *c, const Seperator *sep)
|
||||
if (helper_command_alias_fail(c, "bot_command_taunt", sep->arg[0], "taunt"))
|
||||
return;
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
c->Message(Chat::White, "usage: %s ([option: on | off]) ([actionable: target | byname | ownergroup | botgroup | targetgroup | namesgroup | healrotationtargets | spawned] ([actionable_name]))", sep->arg[0]);
|
||||
c->Message(Chat::White, "usage: %s ([option: on | off]) ([actionable: target | byname | ownergroup | targetgroup | namesgroup | healrotationtargets | spawned] ([actionable_name]))", sep->arg[0]);
|
||||
return;
|
||||
}
|
||||
const int ab_mask = ActionableBots::ABM_Type1;
|
||||
@@ -5044,7 +5043,7 @@ void bot_subcommand_bot_camp(Client *c, const Seperator *sep)
|
||||
if (helper_command_alias_fail(c, "bot_subcommand_bot_camp", sep->arg[0], "botcamp"))
|
||||
return;
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
c->Message(Chat::White, "usage: %s ([actionable: target | byname | ownergroup | botgroup | targetgroup | namesgroup | healrotation | spawned] ([actionable_name]))", sep->arg[0]);
|
||||
c->Message(Chat::White, "usage: %s ([actionable: target | byname | ownergroup | targetgroup | namesgroup | healrotation | spawned] ([actionable_name]))", sep->arg[0]);
|
||||
return;
|
||||
}
|
||||
const int ab_mask = ActionableBots::ABM_NoFilter;
|
||||
@@ -5628,7 +5627,7 @@ void bot_subcommand_bot_dye_armor(Client *c, const Seperator *sep)
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Usage: {} [Material Slot] [Red: 0-255] [Green: 0-255] [Blue: 0-255] ([actionable: target | byname | ownergroup | botgroup | targetgroup | namesgroup | healrotation | spawned] ([actionable_name]))",
|
||||
"Usage: {} [Material Slot] [Red: 0-255] [Green: 0-255] [Blue: 0-255] ([actionable: target | byname | ownergroup | targetgroup | namesgroup | healrotation | spawned] ([actionable_name]))",
|
||||
sep->arg[0]
|
||||
).c_str()
|
||||
);
|
||||
@@ -5835,8 +5834,8 @@ void bot_subcommand_bot_follow_distance(Client *c, const Seperator *sep)
|
||||
if (helper_command_alias_fail(c, "bot_subcommand_bot_follow_distance", sep->arg[0], "botfollowdistance"))
|
||||
return;
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
c->Message(Chat::White, "usage: %s [set] [distance] ([actionable: target | byname | ownergroup | botgroup | targetgroup | namesgroup | healrotation | spawned] ([actionable_name]))", sep->arg[0]);
|
||||
c->Message(Chat::White, "usage: %s [clear] ([actionable: target | byname | ownergroup | botgroup | targetgroup | namesgroup | healrotation | spawned] ([actionable_name]))", sep->arg[0]);
|
||||
c->Message(Chat::White, "usage: %s [set] [distance] ([actionable: target | byname | ownergroup | targetgroup | namesgroup | healrotation | spawned] ([actionable_name]))", sep->arg[0]);
|
||||
c->Message(Chat::White, "usage: %s [clear] ([actionable: target | byname | ownergroup | targetgroup | namesgroup | healrotation | spawned] ([actionable_name]))", sep->arg[0]);
|
||||
return;
|
||||
}
|
||||
const int ab_mask = ActionableBots::ABM_NoFilter;
|
||||
@@ -6010,7 +6009,7 @@ void bot_subcommand_bot_inspect_message(Client *c, const Seperator *sep)
|
||||
if (helper_command_alias_fail(c, "bot_subcommand_bot_inspect_message", sep->arg[0], "botinspectmessage"))
|
||||
return;
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
c->Message(Chat::White, "usage: %s [set | clear] ([actionable: target | byname | ownergroup | botgroup | targetgroup | namesgroup | healrotation | spawned] ([actionable_name]))", sep->arg[0]);
|
||||
c->Message(Chat::White, "usage: %s [set | clear] ([actionable: target | byname | ownergroup | targetgroup | namesgroup | healrotation | spawned] ([actionable_name]))", sep->arg[0]);
|
||||
c->Message(Chat::White, "Notes:");
|
||||
if (c->ClientVersion() >= EQ::versions::ClientVersion::SoF) {
|
||||
c->Message(Chat::White, "- Self-inspect and type your bot's inspect message");
|
||||
@@ -6392,7 +6391,7 @@ void bot_subcommand_bot_report(Client *c, const Seperator *sep)
|
||||
if (helper_command_alias_fail(c, "bot_subcommand_bot_report", sep->arg[0], "botreport"))
|
||||
return;
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
c->Message(Chat::White, "usage: %s ([actionable: target | byname | ownergroup | botgroup | targetgroup | namesgroup | healrotation | spawned] ([actionable_name]))", sep->arg[0]);
|
||||
c->Message(Chat::White, "usage: %s ([actionable: target | byname | ownergroup | targetgroup | namesgroup | healrotation | spawned] ([actionable_name]))", sep->arg[0]);
|
||||
return;
|
||||
}
|
||||
const int ab_mask = ActionableBots::ABM_NoFilter;
|
||||
@@ -6751,7 +6750,7 @@ void bot_subcommand_bot_summon(Client *c, const Seperator *sep)
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Usage: {} ([actionable: target | byname | ownergroup | botgroup | targetgroup | namesgroup | healrotation | spawned] ([actionable_name]))",
|
||||
"Usage: {} ([actionable: target | byname | ownergroup | targetgroup | namesgroup | healrotation | spawned] ([actionable_name]))",
|
||||
sep->arg[0]
|
||||
).c_str()
|
||||
);
|
||||
@@ -6896,7 +6895,7 @@ void bot_subcommand_bot_toggle_helm(Client *c, const Seperator *sep)
|
||||
if (helper_command_alias_fail(c, "bot_subcommand_bot_toggle_helm", sep->arg[0], "bottogglehelm"))
|
||||
return;
|
||||
if (helper_is_help_or_usage(sep->arg[1])) {
|
||||
c->Message(Chat::White, "usage: %s ([option: on | off]) ([actionable: target | byname | ownergroup | botgroup | targetgroup | namesgroup | healrotation | spawned] ([actionable_name]))", sep->arg[0]);
|
||||
c->Message(Chat::White, "usage: %s ([option: on | off]) ([actionable: target | byname | ownergroup | targetgroup | namesgroup | healrotation | spawned] ([actionable_name]))", sep->arg[0]);
|
||||
return;
|
||||
}
|
||||
const int ab_mask = ActionableBots::ABM_NoFilter;
|
||||
@@ -8576,7 +8575,7 @@ 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(Chat::White, "usage: %s ([actionable: target | byname | ownergroup | botgroup | targetgroup | namesgroup | healrotation | spawned] ([actionable_name]))", sep->arg[0]);
|
||||
c->Message(Chat::White, "usage: %s ([actionable: target | byname | ownergroup | targetgroup | namesgroup | healrotation | spawned] ([actionable_name]))", sep->arg[0]);
|
||||
return;
|
||||
}
|
||||
int ab_mask = ActionableBots::ABM_NoFilter;
|
||||
@@ -8819,26 +8818,28 @@ void helper_bot_appearance_form_final(Client *bot_owner, Bot *my_bot)
|
||||
|
||||
void helper_bot_appearance_form_update(Bot *my_bot)
|
||||
{
|
||||
if (!my_bot)
|
||||
if (!my_bot) {
|
||||
return;
|
||||
}
|
||||
|
||||
my_bot->SendIllusionPacket(
|
||||
my_bot->GetRace(),
|
||||
my_bot->GetGender(),
|
||||
0xFF, //my_bot->GetTexture(), // 0xFF - change back if issues arise
|
||||
0xFF, //my_bot->GetHelmTexture(), // 0xFF - change back if issues arise
|
||||
my_bot->GetHairColor(),
|
||||
my_bot->GetBeardColor(),
|
||||
my_bot->GetEyeColor1(),
|
||||
my_bot->GetEyeColor2(),
|
||||
my_bot->GetHairStyle(),
|
||||
my_bot->GetLuclinFace(),
|
||||
my_bot->GetBeard(),
|
||||
0xFF, // aa_title (0xFF)
|
||||
my_bot->GetDrakkinHeritage(),
|
||||
my_bot->GetDrakkinTattoo(),
|
||||
my_bot->GetDrakkinDetails(),
|
||||
my_bot->GetSize()
|
||||
AppearanceStruct{
|
||||
.beard = my_bot->GetBeard(),
|
||||
.beard_color = my_bot->GetBeardColor(),
|
||||
.drakkin_details = my_bot->GetDrakkinDetails(),
|
||||
.drakkin_heritage = my_bot->GetDrakkinHeritage(),
|
||||
.drakkin_tattoo = my_bot->GetDrakkinTattoo(),
|
||||
.eye_color_one = my_bot->GetEyeColor1(),
|
||||
.eye_color_two = my_bot->GetEyeColor2(),
|
||||
.face = my_bot->GetLuclinFace(),
|
||||
.gender_id = my_bot->GetGender(),
|
||||
.hair = my_bot->GetHairStyle(),
|
||||
.hair_color = my_bot->GetHairColor(),
|
||||
.helmet_texture = my_bot->GetHelmTexture(),
|
||||
.race_id = my_bot->GetRace(),
|
||||
.size = my_bot->GetSize(),
|
||||
.texture = my_bot->GetTexture(),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -10002,7 +10003,7 @@ void bot_command_pickpocket(Client *c, const Seperator *sep)
|
||||
if (helper_command_disabled(c, RuleB(Bots, AllowPickpocketCommand), "pickpocket")) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (helper_command_alias_fail(c, "bot_command_pickpocket", sep->arg[0], "pickpocket")) {
|
||||
return;
|
||||
}
|
||||
@@ -10037,7 +10038,7 @@ void bot_command_pickpocket(Client *c, const Seperator *sep)
|
||||
float mob_xy_distance = ((mob_distance.x * mob_distance.x) + (mob_distance.y * mob_distance.y));
|
||||
float mob_z_distance = (mob_distance.z * mob_distance.z);
|
||||
float z_offset_diff = target_mob->GetZOffset() - c->GetZOffset();
|
||||
|
||||
|
||||
if (mob_z_distance >= (35-z_offset_diff) || mob_xy_distance > 250) {
|
||||
c->Message(Chat::White, "You must be closer to an enemy to use this command");
|
||||
return;
|
||||
|
||||
@@ -464,7 +464,8 @@ bool BotDatabase::LoadBot(const uint32 bot_id, Bot*& loaded_bot)
|
||||
l.spells_id,
|
||||
l.time_spawned,
|
||||
l.zone_id,
|
||||
t
|
||||
t,
|
||||
l.expansion_bitmask
|
||||
);
|
||||
|
||||
if (loaded_bot) {
|
||||
@@ -479,8 +480,6 @@ bool BotDatabase::LoadBot(const uint32 bot_id, Bot*& loaded_bot)
|
||||
|
||||
loaded_bot->SetStopMeleeLevel(l.stop_melee_level);
|
||||
|
||||
loaded_bot->SetExpansionBitmask(l.expansion_bitmask, false);
|
||||
|
||||
loaded_bot->SetBotEnforceSpellSetting((l.enforce_spell_settings ? true : false));
|
||||
|
||||
loaded_bot->SetBotArcherySetting((l.archery_setting ? true : false));
|
||||
|
||||
+39
-2
@@ -8883,7 +8883,8 @@ void Client::ShowDevToolsMenu()
|
||||
menu_reload_two += Saylink::Silent("#reload commands", "Commands");
|
||||
menu_reload_two += " | " + Saylink::Silent("#reload content_flags", "Content Flags");
|
||||
|
||||
menu_reload_three += Saylink::Silent("#reload doors", "Doors");
|
||||
menu_reload_three += Saylink::Silent("#reload data_buckets_cache", "Databuckets");
|
||||
menu_reload_three += " | " + Saylink::Silent("#reload doors", "Doors");
|
||||
menu_reload_three += " | " + Saylink::Silent("#reload ground_spawns", "Ground Spawns");
|
||||
|
||||
menu_reload_four += Saylink::Silent("#reload logs", "Level Based Experience Modifiers");
|
||||
@@ -10837,6 +10838,16 @@ void Client::SendReloadCommandMessages() {
|
||||
).c_str()
|
||||
);
|
||||
|
||||
auto data_buckets_link = Saylink::Silent("#reload data_buckets_cache");
|
||||
|
||||
Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Usage: {} - Reloads data buckets cache globally",
|
||||
data_buckets_link
|
||||
).c_str()
|
||||
);
|
||||
|
||||
auto dztemplates_link = Saylink::Silent("#reload dztemplates");
|
||||
Message(Chat::White, fmt::format("Usage: {} - Reloads Dynamic Zone Templates globally", dztemplates_link).c_str());
|
||||
|
||||
@@ -11739,7 +11750,7 @@ void Client::ShowSpells(Client* c, ShowSpellType show_spell_type)
|
||||
"{}. {} ({})",
|
||||
index,
|
||||
GetSpellName(spell_id),
|
||||
Strings::Commify(spell_id)
|
||||
spell_id
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
@@ -11757,3 +11768,29 @@ void Client::ShowSpells(Client* c, ShowSpellType show_spell_type)
|
||||
spell_table.c_str()
|
||||
);
|
||||
}
|
||||
|
||||
std::string GetZoneModeString(ZoneMode mode)
|
||||
{
|
||||
switch (mode) {
|
||||
case ZoneToSafeCoords:
|
||||
return "ZoneToSafeCoords";
|
||||
case GMSummon:
|
||||
return "GMSummon";
|
||||
case ZoneToBindPoint:
|
||||
return "ZoneToBindPoint";
|
||||
case ZoneSolicited:
|
||||
return "ZoneSolicited";
|
||||
case ZoneUnsolicited:
|
||||
return "ZoneUnsolicited";
|
||||
case GateToBindPoint:
|
||||
return "GateToBindPoint";
|
||||
case SummonPC:
|
||||
return "SummonPC";
|
||||
case Rewind:
|
||||
return "Rewind";
|
||||
case EvacToSafeCoords:
|
||||
return "EvacToSafeCoords";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,6 +123,9 @@ typedef enum {
|
||||
EvacToSafeCoords
|
||||
} ZoneMode;
|
||||
|
||||
// translate above enum to a string
|
||||
std::string GetZoneModeString(ZoneMode mode);
|
||||
|
||||
enum {
|
||||
HideCorpseNone = 0,
|
||||
HideCorpseAll = 1,
|
||||
@@ -233,6 +236,7 @@ public:
|
||||
~Client();
|
||||
|
||||
void ReconnectUCS();
|
||||
void RecordStats();
|
||||
|
||||
void SetDisplayMobInfoWindow(bool display_mob_info_window);
|
||||
bool GetDisplayMobInfoWindow() const;
|
||||
@@ -381,6 +385,7 @@ public:
|
||||
inline PetInfo* GetPetInfo(uint16 pet) { return (pet==1)?&m_suspendedminion:&m_petinfo; }
|
||||
inline InspectMessage_Struct& GetInspectMessage() { return m_inspect_message; }
|
||||
inline const InspectMessage_Struct& GetInspectMessage() const { return m_inspect_message; }
|
||||
void ReloadExpansionProfileSetting();
|
||||
|
||||
void SetPetCommandState(int button, int state);
|
||||
|
||||
|
||||
+104
-8
@@ -62,6 +62,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#include "../common/repositories/account_repository.h"
|
||||
|
||||
#include "../common/events/player_event_logs.h"
|
||||
#include "../common/repositories/character_stats_record_repository.h"
|
||||
|
||||
extern QueryServ* QServ;
|
||||
extern Zone* zone;
|
||||
@@ -915,6 +916,8 @@ void Client::CompleteConnect()
|
||||
|
||||
heroforge_wearchange_timer.Start(250);
|
||||
|
||||
RecordStats();
|
||||
|
||||
// enforce some rules..
|
||||
if (!CanEnterZone()) {
|
||||
LogInfo("Kicking character [{}] from zone, not allowed here (missing requirements)", GetCleanName());
|
||||
@@ -1442,12 +1445,7 @@ 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; }
|
||||
|
||||
if (RuleB(World, UseClientBasedExpansionSettings)) {
|
||||
m_pp.expansions = EQ::expansions::ConvertClientVersionToExpansionsMask(ClientVersion());
|
||||
}
|
||||
else {
|
||||
m_pp.expansions = (RuleI(World, ExpansionSettings) & EQ::expansions::ConvertClientVersionToExpansionsMask(ClientVersion()));
|
||||
}
|
||||
ReloadExpansionProfileSetting();
|
||||
|
||||
if (!database.LoadAlternateAdvancement(this)) {
|
||||
LogError("Error loading AA points for [{}]", GetName());
|
||||
@@ -2138,7 +2136,7 @@ void Client::Handle_OP_AdventureMerchantRequest(const EQApplicationPacket *app)
|
||||
const EQ::ItemData *item = nullptr;
|
||||
std::list<MerchantList> merlist = zone->merchanttable[merchantid];
|
||||
std::list<MerchantList>::const_iterator itr;
|
||||
for (itr = merlist.begin(); itr != merlist.end() && count<255; ++itr) {
|
||||
for (itr = merlist.begin(); itr != merlist.end(); ++itr) {
|
||||
const MerchantList &ml = *itr;
|
||||
if (GetLevel() < ml.level_required) {
|
||||
continue;
|
||||
@@ -15953,7 +15951,7 @@ void Client::Handle_OP_XTargetRequest(const EQApplicationPacket *app)
|
||||
if (t.type == Type) {
|
||||
Raid* r = GetRaid();
|
||||
if (r) {
|
||||
auto mm = entity_list.GetNPCByID(r->marked_npcs[t.assist_slot]);
|
||||
auto mm = entity_list.GetNPCByID(r->marked_npcs[t.assist_slot].entity_id);
|
||||
if (mm) {
|
||||
UpdateXTargetType(t.type, mm->CastToMob(), mm->CastToMob()->GetName());
|
||||
}
|
||||
@@ -16392,3 +16390,101 @@ void Client::Handle_OP_RaidClearNPCMarks(const EQApplicationPacket* app)
|
||||
r->RaidClearNPCMarks(this);
|
||||
}
|
||||
}
|
||||
|
||||
void Client::RecordStats()
|
||||
{
|
||||
auto r = CharacterStatsRecordRepository::FindOne(
|
||||
database,
|
||||
CharacterID()
|
||||
);
|
||||
|
||||
r.status = Admin();
|
||||
r.name = GetCleanName();
|
||||
r.aa_points = GetAAPoints() + GetSpentAA();
|
||||
r.level = GetLevel();
|
||||
r.class_ = GetBaseClass();
|
||||
r.race = GetBaseRace();
|
||||
r.hp = GetMaxHP() - GetSpellBonuses().HP;
|
||||
r.mana = GetMaxMana() - GetSpellBonuses().Mana;
|
||||
r.endurance = GetMaxEndurance() - GetSpellBonuses().Endurance;
|
||||
r.ac = GetDisplayAC() - GetSpellBonuses().AC;
|
||||
r.strength = GetSTR() - GetSpellBonuses().STR;
|
||||
r.stamina = GetSTA() - GetSpellBonuses().STA;
|
||||
r.dexterity = GetDEX() - GetSpellBonuses().DEX;
|
||||
r.agility = GetAGI() - GetSpellBonuses().AGI;
|
||||
r.intelligence = GetINT() - GetSpellBonuses().INT;
|
||||
r.wisdom = GetWIS() - GetSpellBonuses().WIS;
|
||||
r.charisma = GetCHA() - GetSpellBonuses().CHA;
|
||||
r.magic_resist = GetMR() - GetSpellBonuses().MR;
|
||||
r.fire_resist = GetFR() - GetSpellBonuses().FR;
|
||||
r.cold_resist = GetCR() - GetSpellBonuses().CR;
|
||||
r.poison_resist = GetPR() - GetSpellBonuses().PR;
|
||||
r.disease_resist = GetDR() - GetSpellBonuses().DR;
|
||||
r.corruption_resist = GetCorrup() - GetSpellBonuses().Corrup;
|
||||
r.heroic_strength = GetHeroicSTR() - GetSpellBonuses().HeroicSTR;
|
||||
r.heroic_stamina = GetHeroicSTA() - GetSpellBonuses().HeroicSTA;
|
||||
r.heroic_dexterity = GetHeroicDEX() - GetSpellBonuses().HeroicDEX;
|
||||
r.heroic_agility = GetHeroicAGI() - GetSpellBonuses().HeroicAGI;
|
||||
r.heroic_intelligence = GetHeroicINT() - GetSpellBonuses().HeroicINT;
|
||||
r.heroic_wisdom = GetHeroicWIS() - GetSpellBonuses().HeroicWIS;
|
||||
r.heroic_charisma = GetHeroicCHA() - GetSpellBonuses().HeroicCHA;
|
||||
r.heroic_magic_resist = GetHeroicMR() - GetSpellBonuses().HeroicMR;
|
||||
r.heroic_fire_resist = GetHeroicFR() - GetSpellBonuses().HeroicFR;
|
||||
r.heroic_cold_resist = GetHeroicCR() - GetSpellBonuses().HeroicCR;
|
||||
r.heroic_poison_resist = GetHeroicPR() - GetSpellBonuses().HeroicPR;
|
||||
r.heroic_disease_resist = GetHeroicDR() - GetSpellBonuses().HeroicDR;
|
||||
r.heroic_corruption_resist = GetHeroicCorrup() - GetSpellBonuses().HeroicCorrup;
|
||||
r.haste = GetHaste();
|
||||
r.accuracy = GetAccuracy() - GetSpellBonuses().Accuracy[EQ::skills::HIGHEST_SKILL + 1];
|
||||
r.attack = GetTotalATK() - GetSpellBonuses().ATK;
|
||||
r.avoidance = GetAvoidance() - GetSpellBonuses().AvoidMeleeChance;
|
||||
r.clairvoyance = GetClair() - GetSpellBonuses().Clairvoyance;
|
||||
r.combat_effects = GetCombatEffects() - GetSpellBonuses().ProcChance;
|
||||
r.damage_shield_mitigation = GetDSMit() - GetSpellBonuses().DSMitigation;
|
||||
r.damage_shield = GetDS() - GetSpellBonuses().DamageShield;
|
||||
r.dot_shielding = GetDoTShield() - GetSpellBonuses().DoTShielding;
|
||||
r.hp_regen = GetHPRegen() - GetSpellBonuses().HPRegen;
|
||||
r.mana_regen = GetManaRegen() - GetSpellBonuses().ManaRegen;
|
||||
r.endurance_regen = GetEnduranceRegen() - GetSpellBonuses().EnduranceRegen;
|
||||
r.shielding = GetShielding() - GetSpellBonuses().MeleeMitigation;
|
||||
r.spell_damage = GetSpellDmg() - GetSpellBonuses().SpellDmg;
|
||||
r.spell_shielding = GetSpellShield() - GetSpellBonuses().SpellShield;
|
||||
r.strikethrough = GetStrikeThrough() - GetSpellBonuses().StrikeThrough;
|
||||
r.stun_resist = GetStunResist() - GetSpellBonuses().StunResist;
|
||||
r.backstab = 0;
|
||||
r.wind = GetWindMod();
|
||||
r.brass = GetBrassMod();
|
||||
r.string = GetStringMod();
|
||||
r.percussion = GetPercMod();
|
||||
r.singing = GetSingMod();
|
||||
r.baking = GetSkill(EQ::skills::SkillType::SkillBaking);
|
||||
r.alchemy = GetSkill(EQ::skills::SkillType::SkillAlchemy);
|
||||
r.jewelry = GetSkill(EQ::skills::SkillType::SkillJewelryMaking);
|
||||
r.tailoring = GetSkill(EQ::skills::SkillType::SkillTailoring);
|
||||
r.blacksmithing = GetSkill(EQ::skills::SkillType::SkillBlacksmithing);
|
||||
r.fletching = GetSkill(EQ::skills::SkillType::SkillFletching);
|
||||
r.brewing = GetSkill(EQ::skills::SkillType::SkillBrewing);
|
||||
r.fishing = GetSkill(EQ::skills::SkillType::SkillFishing);
|
||||
r.pottery = GetSkill(EQ::skills::SkillType::SkillPottery);
|
||||
r.alcohol = GetSkill(EQ::skills::SkillType::SkillAlcoholTolerance);
|
||||
r.tinkering = GetSkill(EQ::skills::SkillType::SkillTinkering);
|
||||
r.updated_at = std::time(nullptr);
|
||||
|
||||
if (r.character_id > 0) {
|
||||
CharacterStatsRecordRepository::UpdateOne(database, r);
|
||||
} else {
|
||||
r.character_id = CharacterID();
|
||||
r.created_at = std::time(nullptr);
|
||||
CharacterStatsRecordRepository::InsertOne(database, r);
|
||||
}
|
||||
}
|
||||
|
||||
void Client::ReloadExpansionProfileSetting()
|
||||
{
|
||||
if (RuleB(World, UseClientBasedExpansionSettings)) {
|
||||
m_pp.expansions = EQ::expansions::ConvertClientVersionToExpansionsMask(ClientVersion());
|
||||
}
|
||||
else {
|
||||
m_pp.expansions = RuleI(World, ExpansionSettings);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -741,6 +741,8 @@ void Client::OnDisconnect(bool hard_disconnect) {
|
||||
parse->EventPlayer(EVENT_DISCONNECT, this, "", 0);
|
||||
}
|
||||
|
||||
RecordStats();
|
||||
|
||||
Disconnect();
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -30,6 +30,7 @@ uint8 GetCommandStatus(std::string command_name);
|
||||
void ListModifyNPCStatMap(Client *c);
|
||||
std::map<std::string, std::string> GetModifyNPCStatMap();
|
||||
std::string GetModifyNPCStatDescription(std::string stat);
|
||||
void SendFeatureSubCommands(Client *c);
|
||||
void SendNPCEditSubCommands(Client *c);
|
||||
void SendRuleSubCommands(Client *c);
|
||||
void SendGuildSubCommands(Client *c);
|
||||
@@ -134,7 +135,7 @@ void command_petitems(Client *c, const Seperator *sep);
|
||||
void command_picklock(Client *c, const Seperator *sep);
|
||||
void command_profanity(Client *c, const Seperator *sep);
|
||||
void command_push(Client *c, const Seperator *sep);
|
||||
void command_pvp(Client *c, const Seperator *sep);;
|
||||
void command_pvp(Client *c, const Seperator *sep);
|
||||
void command_raidloot(Client* c, const Seperator* sep);
|
||||
void command_randomfeatures(Client *c, const Seperator *sep);
|
||||
void command_refreshgroup(Client *c, const Seperator *sep);
|
||||
|
||||
+1
-1
@@ -891,7 +891,7 @@ struct ExtraAttackOptions {
|
||||
int hit_chance;
|
||||
int melee_damage_bonus_flat;
|
||||
int skilldmgtaken_bonus_flat;
|
||||
|
||||
int range_percent;
|
||||
};
|
||||
|
||||
struct DamageTable {
|
||||
|
||||
+22
-14
@@ -551,6 +551,8 @@ void DataBucket::HandleWorldMessage(ServerPacket *p)
|
||||
|
||||
// delete
|
||||
if (n.update_action == DataBucketCacheUpdateAction::Delete) {
|
||||
DeleteFromMissesCache(n.e);
|
||||
|
||||
g_data_bucket_cache.erase(
|
||||
std::remove_if(
|
||||
g_data_bucket_cache.begin(),
|
||||
@@ -577,23 +579,23 @@ void DataBucket::HandleWorldMessage(ServerPacket *p)
|
||||
|
||||
// update
|
||||
bool has_key = false;
|
||||
|
||||
for (auto &ce: g_data_bucket_cache) {
|
||||
int64 time_delta = ce.updated_time - n.updated_time;
|
||||
if (ce.updated_time >= n.updated_time) {
|
||||
LogDataBuckets(
|
||||
"Attempted to update older cache key [{}] rejecting old time [{}] new time [{}] delta [{}] cache_size [{}]",
|
||||
ce.e.key_,
|
||||
ce.updated_time,
|
||||
n.updated_time,
|
||||
time_delta,
|
||||
g_data_bucket_cache.size()
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// update cache
|
||||
if (ce.e.id == n.e.id) {
|
||||
// reject old updates
|
||||
int64 time_delta = ce.updated_time - n.updated_time;
|
||||
if (ce.updated_time >= n.updated_time) {
|
||||
LogDataBuckets(
|
||||
"Attempted to update older cache key [{}] rejecting old time [{}] new time [{}] delta [{}] cache_size [{}]",
|
||||
ce.e.key_,
|
||||
ce.updated_time,
|
||||
n.updated_time,
|
||||
time_delta,
|
||||
g_data_bucket_cache.size()
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
DeleteFromMissesCache(n.e);
|
||||
|
||||
LogDataBuckets(
|
||||
@@ -663,3 +665,9 @@ void DataBucket::DeleteFromMissesCache(DataBucketsRepository::DataBuckets e)
|
||||
g_data_bucket_cache.size()
|
||||
);
|
||||
}
|
||||
|
||||
void DataBucket::ClearCache()
|
||||
{
|
||||
g_data_bucket_cache.clear();
|
||||
LogInfo("Cleared data buckets cache");
|
||||
}
|
||||
|
||||
@@ -88,6 +88,7 @@ public:
|
||||
static bool SendDataBucketCacheUpdate(const DataBucketCacheEntry &e);
|
||||
static void HandleWorldMessage(ServerPacket *p);
|
||||
static void DeleteFromMissesCache(DataBucketsRepository::DataBuckets e);
|
||||
static void ClearCache();
|
||||
};
|
||||
|
||||
#endif //EQEMU_DATABUCKET_H
|
||||
|
||||
@@ -83,6 +83,8 @@ Doors::Doors(const DoorsRepository::Doors &door) :
|
||||
m_close_timer.Disable();
|
||||
|
||||
m_disable_timer = (door.disable_timer == 1 ? true : false);
|
||||
|
||||
m_is_blacklisted_to_open = GetIsDoorBlacklisted();
|
||||
}
|
||||
|
||||
Doors::Doors(const char *model, const glm::vec4 &position, uint8 open_type, uint16 size) :
|
||||
@@ -901,3 +903,27 @@ bool Doors::IsDestinationZoneSame() const
|
||||
{
|
||||
return m_same_destination_zone;
|
||||
}
|
||||
|
||||
// IsDoorBlacklisted has a static list of doors that are blacklisted
|
||||
// from being opened by NPCs. This is used to prevent NPCs from opening
|
||||
// doors that are not meant to be opened by NPCs.
|
||||
bool Doors::GetIsDoorBlacklisted()
|
||||
{
|
||||
std::vector<std::string> blacklist = {
|
||||
"TOGGLE",
|
||||
"PNDRESSER101",
|
||||
};
|
||||
|
||||
for (auto& name : blacklist) {
|
||||
std::string door_name = GetDoorName();
|
||||
if (name == door_name) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Doors::IsDoorBlacklisted() {
|
||||
return m_is_blacklisted_to_open;
|
||||
}
|
||||
|
||||
@@ -69,7 +69,10 @@ public:
|
||||
bool HasDestinationZone() const;
|
||||
bool IsDestinationZoneSame() const;
|
||||
|
||||
bool IsDoorBlacklisted();
|
||||
|
||||
private:
|
||||
bool GetIsDoorBlacklisted();
|
||||
|
||||
bool m_has_destination_zone = false;
|
||||
bool m_same_destination_zone = false;
|
||||
@@ -99,5 +102,6 @@ private:
|
||||
uint8 m_is_ldon_door;
|
||||
int m_dz_switch_id = 0;
|
||||
uint32 m_client_version_mask;
|
||||
bool m_is_blacklisted_to_open = false; // is door blacklisted to open by npcs
|
||||
};
|
||||
#endif
|
||||
|
||||
+1
-1
@@ -95,7 +95,7 @@ int64 Mob::GetActSpellDamage(uint16 spell_id, int64 value, Mob* target) {
|
||||
else if ((IsOfClientBot() && GetClass() == WIZARD) || (IsMerc() && GetClass() == CASTERDPS)) {
|
||||
if ((GetLevel() >= RuleI(Spells, WizCritLevel)) && zone->random.Roll(RuleI(Spells, WizCritChance))){
|
||||
//Wizard innate critical chance is calculated seperately from spell effect and is not a set ratio. (20-70 is parse confirmed)
|
||||
ratio += zone->random.Int(20,70);
|
||||
ratio += zone->random.Int(RuleI(Spells, WizardCritMinimumRandomRatio), RuleI(Spells, WizardCritMaximumRandomRatio));
|
||||
Critical = true;
|
||||
}
|
||||
}
|
||||
|
||||
+10
-9
@@ -1047,42 +1047,42 @@ void Perl__processmobswhilezoneempty(bool on)
|
||||
quest_manager.processmobswhilezoneempty(on);
|
||||
}
|
||||
|
||||
void Perl__npcrace(int race_id)
|
||||
void Perl__npcrace(uint16 race_id)
|
||||
{
|
||||
quest_manager.npcrace(race_id);
|
||||
}
|
||||
|
||||
void Perl__npcgender(int gender_id)
|
||||
void Perl__npcgender(uint8 gender_id)
|
||||
{
|
||||
quest_manager.npcgender(gender_id);
|
||||
}
|
||||
|
||||
void Perl__npcsize(int size)
|
||||
void Perl__npcsize(float size)
|
||||
{
|
||||
quest_manager.npcsize(size);
|
||||
}
|
||||
|
||||
void Perl__npctexture(int texture_id)
|
||||
void Perl__npctexture(uint8 texture_id)
|
||||
{
|
||||
quest_manager.npctexture(texture_id);
|
||||
}
|
||||
|
||||
void Perl__playerrace(int race_id)
|
||||
void Perl__playerrace(uint16 race_id)
|
||||
{
|
||||
quest_manager.playerrace(race_id);
|
||||
}
|
||||
|
||||
void Perl__playergender(int gender_id)
|
||||
void Perl__playergender(uint8 gender_id)
|
||||
{
|
||||
quest_manager.playergender(gender_id);
|
||||
}
|
||||
|
||||
void Perl__playersize(int newsize)
|
||||
void Perl__playersize(float size)
|
||||
{
|
||||
quest_manager.playersize(newsize);
|
||||
quest_manager.playersize(size);
|
||||
}
|
||||
|
||||
void Perl__playertexture(int texture_id)
|
||||
void Perl__playertexture(uint8 texture_id)
|
||||
{
|
||||
quest_manager.playertexture(texture_id);
|
||||
}
|
||||
@@ -2746,6 +2746,7 @@ bool Perl__IsContentFlagEnabled(std::string flag_name)
|
||||
void Perl__SetContentFlag(std::string flag_name, bool enabled)
|
||||
{
|
||||
content_service.SetContentFlag(flag_name, enabled);
|
||||
zone->ReloadContentFlags();
|
||||
}
|
||||
|
||||
Expedition* Perl__get_expedition()
|
||||
|
||||
@@ -18,10 +18,6 @@ Eglin
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
// this option disables distinct int/float/string function argument types for
|
||||
// backwards compatibility with current perl api usage
|
||||
// e.g. quest::settimer(0, 1) using number for timer name instead of string
|
||||
#define PERLBIND_NO_STRICT_SCALAR_TYPES
|
||||
#include <perlbind/perlbind.h>
|
||||
namespace perl = perlbind;
|
||||
|
||||
|
||||
+21
-16
@@ -674,6 +674,8 @@ 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);
|
||||
|
||||
if (parse->HasQuestSub(npc->GetNPCTypeID(), EVENT_SPAWN)) {
|
||||
parse->EventNPC(EVENT_SPAWN, npc, nullptr, "", 0);
|
||||
}
|
||||
@@ -713,8 +715,6 @@ void EntityList::AddNPC(NPC *npc, bool send_spawn_packet, bool dont_queue)
|
||||
|
||||
npc->SendPositionToClients();
|
||||
|
||||
entity_list.ScanCloseMobs(npc->close_mobs, npc, true);
|
||||
|
||||
if (parse->HasQuestSub(ZONE_CONTROLLER_NPC_ID, EVENT_SPAWN_ZONE)) {
|
||||
npc->DispatchZoneControllerEvent(EVENT_SPAWN_ZONE, npc, "", 0, nullptr);
|
||||
}
|
||||
@@ -1595,7 +1595,7 @@ void EntityList::RefreshClientXTargets(Client *c)
|
||||
}
|
||||
|
||||
void EntityList::QueueClientsByTarget(Mob *sender, const EQApplicationPacket *app,
|
||||
bool iSendToSender, Mob *SkipThisMob, bool ackreq, bool HoTT, uint32 ClientVersionBits, bool inspect_buffs)
|
||||
bool iSendToSender, Mob *SkipThisMob, bool ackreq, bool HoTT, uint32 ClientVersionBits, bool inspect_buffs, bool clear_target_window)
|
||||
{
|
||||
auto it = client_list.begin();
|
||||
while (it != client_list.end()) {
|
||||
@@ -1623,23 +1623,25 @@ void EntityList::QueueClientsByTarget(Mob *sender, const EQApplicationPacket *ap
|
||||
if (c != sender) {
|
||||
if (Target == sender) {
|
||||
if (inspect_buffs) { // if inspect_buffs is true we're sending a mob's buffs to those with the LAA
|
||||
Send = clear_target_window;
|
||||
if (c->GetGM() || RuleB(Spells, AlwaysSendTargetsBuffs)) {
|
||||
Send = true;
|
||||
Send = !clear_target_window;
|
||||
} else if (c->IsRaidGrouped()) {
|
||||
Raid *raid = c->GetRaid();
|
||||
if (!raid)
|
||||
continue;
|
||||
uint32 gid = raid->GetGroup(c);
|
||||
if (gid > 11 || raid->GroupCount(gid) < 3)
|
||||
continue;
|
||||
if (raid->GetLeadershipAA(groupAAInspectBuffs, gid))
|
||||
Send = true;
|
||||
if (raid) {
|
||||
uint32 gid = raid->GetGroup(c);
|
||||
if (gid < MAX_RAID_GROUPS && raid->GroupCount(gid) >= 3) {
|
||||
if (raid->GetLeadershipAA(groupAAInspectBuffs, gid))
|
||||
Send = !clear_target_window;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Group *group = c->GetGroup();
|
||||
if (!group || group->GroupCount() < 3)
|
||||
continue;
|
||||
if (group->GetLeadershipAA(groupAAInspectBuffs))
|
||||
Send = true;
|
||||
if (group && group->GroupCount() >= 3) {
|
||||
if (group->GetLeadershipAA(groupAAInspectBuffs)) {
|
||||
Send = !clear_target_window;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Send = true;
|
||||
@@ -1649,8 +1651,9 @@ void EntityList::QueueClientsByTarget(Mob *sender, const EQApplicationPacket *ap
|
||||
}
|
||||
}
|
||||
|
||||
if (Send && (c->ClientVersionBit() & ClientVersionBits))
|
||||
if (Send && (c->ClientVersionBit() & ClientVersionBits)) {
|
||||
c->QueuePacket(app, ackreq);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5647,6 +5650,8 @@ void EntityList::StopMobAI()
|
||||
|
||||
void EntityList::SendAlternateAdvancementStats() {
|
||||
for (auto &c : client_list) {
|
||||
c.second->Message(Chat::White, "Reloading AA");
|
||||
c.second->ReloadExpansionProfileSetting();
|
||||
c.second->SendClearPlayerAA();
|
||||
c.second->SendAlternateAdvancementTable();
|
||||
c.second->SendAlternateAdvancementStats();
|
||||
|
||||
+1
-2
@@ -413,8 +413,7 @@ public:
|
||||
void QueueClientsStatus(Mob* sender, const EQApplicationPacket* app, bool ignore_sender = false, uint8 minstatus = AccountStatus::Player, uint8 maxstatus = AccountStatus::Player);
|
||||
void QueueClientsGuild(Mob* sender, const EQApplicationPacket* app, bool ignore_sender = false, uint32 guildeqid = 0);
|
||||
void QueueClientsGuildBankItemUpdate(const GuildBankItemUpdate_Struct *gbius, uint32 GuildID);
|
||||
void QueueClientsByTarget(Mob* sender, const EQApplicationPacket* app, bool iSendToSender = true, Mob* SkipThisMob = 0, bool ackreq = true,
|
||||
bool HoTT = true, uint32 ClientVersionBits = 0xFFFFFFFF, bool inspect_buffs = false);
|
||||
void QueueClientsByTarget(Mob* sender, const EQApplicationPacket* app, bool iSendToSender = true, Mob* SkipThisMob = 0, bool ackreq = true, bool HoTT = true, uint32 ClientVersionBits = 0xFFFFFFFF, bool inspect_buffs = false, bool clear_target_window = false);
|
||||
|
||||
void QueueClientsByXTarget(Mob* sender, const EQApplicationPacket* app, bool iSendToSender = true, EQ::versions::ClientVersionBitmask client_version_bits = EQ::versions::ClientVersionBitmask::maskAllClients);
|
||||
void QueueToGroupsForNPCHealthAA(Mob* sender, const EQApplicationPacket* app);
|
||||
|
||||
+3
-4
@@ -1181,12 +1181,11 @@ void Raid::SplitExp(const uint64 exp, Mob* other) {
|
||||
const auto highest_level = GetHighestLevel();
|
||||
|
||||
if (RuleB(Character, EnableRaidEXPModifier)) {
|
||||
raid_experience = static_cast<uint64>(
|
||||
static_cast<float>(raid_experience) *
|
||||
(1.0f - RuleR(Character, RaidExpMultiplier))
|
||||
);
|
||||
raid_experience = static_cast<uint64>(static_cast<float>(raid_experience) * (1.0f - RuleR(Character, RaidExpMultiplier)));
|
||||
}
|
||||
|
||||
raid_experience = static_cast<uint64>(static_cast<float>(raid_experience) * RuleR(Character, FinalRaidExpMultiplier));
|
||||
|
||||
const auto consider_level = Mob::GetLevelCon(highest_level, other->GetLevel());
|
||||
if (consider_level == CON_GRAY) {
|
||||
return;
|
||||
|
||||
@@ -39,9 +39,9 @@ void GlobalLootManager::ShowZoneGlobalLoot(Client *c) const
|
||||
global_loot_table += DialogueWindow::TableRow(
|
||||
fmt::format(
|
||||
"{}{}{}",
|
||||
DialogueWindow::TableCell(Strings::Commify(e.GetID())),
|
||||
DialogueWindow::TableCell(std::to_string(e.GetID())),
|
||||
DialogueWindow::TableCell(e.GetDescription()),
|
||||
DialogueWindow::TableCell(Strings::Commify(e.GetLootTableID()))
|
||||
DialogueWindow::TableCell(std::to_string(e.GetLootTableID()))
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -76,9 +76,9 @@ void GlobalLootManager::ShowNPCGlobalLoot(Client *c, NPC *t) const
|
||||
global_loot_table += DialogueWindow::TableRow(
|
||||
fmt::format(
|
||||
"{}{}{}",
|
||||
DialogueWindow::TableCell(Strings::Commify(e.GetID())),
|
||||
DialogueWindow::TableCell(std::to_string(e.GetID())),
|
||||
DialogueWindow::TableCell(e.GetDescription()),
|
||||
DialogueWindow::TableCell(Strings::Commify(e.GetLootTableID()))
|
||||
DialogueWindow::TableCell(std::to_string(e.GetLootTableID()))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -67,23 +67,24 @@ void command_appearanceeffects(Client *c, const Seperator *sep)
|
||||
);
|
||||
} else if (is_remove) {
|
||||
t->SendIllusionPacket(
|
||||
t->GetRace(),
|
||||
t->GetGender(),
|
||||
t->GetTexture(),
|
||||
t->GetHelmTexture(),
|
||||
t->GetHairColor(),
|
||||
t->GetBeardColor(),
|
||||
t->GetEyeColor1(),
|
||||
t->GetEyeColor2(),
|
||||
t->GetHairStyle(),
|
||||
t->GetLuclinFace(),
|
||||
t->GetBeard(),
|
||||
0xFF,
|
||||
t->GetDrakkinHeritage(),
|
||||
t->GetDrakkinTattoo(),
|
||||
t->GetDrakkinDetails(),
|
||||
t->GetSize(),
|
||||
false
|
||||
AppearanceStruct{
|
||||
.beard = t->GetBeard(),
|
||||
.beard_color = t->GetBeardColor(),
|
||||
.drakkin_details = t->GetDrakkinDetails(),
|
||||
.drakkin_heritage = t->GetDrakkinHeritage(),
|
||||
.drakkin_tattoo = t->GetDrakkinTattoo(),
|
||||
.eye_color_one = t->GetEyeColor1(),
|
||||
.eye_color_two = t->GetEyeColor2(),
|
||||
.face = t->GetLuclinFace(),
|
||||
.gender_id = t->GetGender(),
|
||||
.hair = t->GetHairStyle(),
|
||||
.hair_color = t->GetHairColor(),
|
||||
.helmet_texture = t->GetHelmTexture(),
|
||||
.race_id = t->GetRace(),
|
||||
.send_effects = false,
|
||||
.size = t->GetSize(),
|
||||
.texture = t->GetTexture(),
|
||||
}
|
||||
);
|
||||
t->ClearAppearenceEffects();
|
||||
c->Message(
|
||||
|
||||
@@ -41,7 +41,7 @@ void command_bugs(Client *c, const Seperator *sep)
|
||||
|
||||
auto bug_id = Strings::ToUnsignedInt(sep->arg[2]);
|
||||
|
||||
auto r = BugReportsRepository::FindOne(content_db, bug_id);
|
||||
auto r = BugReportsRepository::FindOne(database, bug_id);
|
||||
if (!r.id) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
@@ -55,7 +55,7 @@ void command_bugs(Client *c, const Seperator *sep)
|
||||
|
||||
r.bug_status = 1;
|
||||
|
||||
if (!BugReportsRepository::UpdateOne(content_db, r)) {
|
||||
if (!BugReportsRepository::UpdateOne(database, r)) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
@@ -81,7 +81,7 @@ void command_bugs(Client *c, const Seperator *sep)
|
||||
}
|
||||
|
||||
auto bug_id = Strings::ToUnsignedInt(sep->arg[2]);
|
||||
auto deleted_count = BugReportsRepository::DeleteOne(content_db, bug_id);
|
||||
auto deleted_count = BugReportsRepository::DeleteOne(database, bug_id);
|
||||
if (!deleted_count) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
@@ -112,7 +112,7 @@ void command_bugs(Client *c, const Seperator *sep)
|
||||
auto bug_id = Strings::ToUnsignedInt(sep->arg[2]);
|
||||
auto bug_review = sep->argplus[3];
|
||||
|
||||
auto r = BugReportsRepository::FindOne(content_db, bug_id);
|
||||
auto r = BugReportsRepository::FindOne(database, bug_id);
|
||||
if (!r.id) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
@@ -128,7 +128,7 @@ void command_bugs(Client *c, const Seperator *sep)
|
||||
r.last_reviewer = c->GetCleanName();
|
||||
r.reviewer_notes = bug_review;
|
||||
|
||||
if (!BugReportsRepository::UpdateOne(content_db, r)) {
|
||||
if (!BugReportsRepository::UpdateOne(database, r)) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
@@ -154,7 +154,7 @@ void command_bugs(Client *c, const Seperator *sep)
|
||||
|
||||
auto search_criteria = sep->argplus[2];
|
||||
auto l = BugReportsRepository::GetWhere(
|
||||
content_db,
|
||||
database,
|
||||
fmt::format(
|
||||
"bug_status = 0 AND (character_name LIKE '%%{}%%' OR bug_report LIKE '%%{}%%')",
|
||||
Strings::Escape(search_criteria),
|
||||
@@ -205,7 +205,7 @@ void command_bugs(Client *c, const Seperator *sep)
|
||||
|
||||
auto bug_id = Strings::ToUnsignedInt(sep->arg[2]);
|
||||
|
||||
auto r = BugReportsRepository::FindOne(content_db, bug_id);
|
||||
auto r = BugReportsRepository::FindOne(database, bug_id);
|
||||
if (!r.id) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
|
||||
@@ -47,7 +47,7 @@ void DoorManipulation::CommandHandler(Client *c, const Seperator *sep)
|
||||
const std::string set_size_action = "set_size";
|
||||
|
||||
// we're passing a move action here
|
||||
if (!arg3.empty() && Strings::IsNumber(arg3)) {
|
||||
if (!arg3.empty() && (Strings::IsFloat(arg3) || Strings::IsNumber(arg3))) {
|
||||
float x_move = 0.0f;
|
||||
float y_move = 0.0f;
|
||||
float z_move = 0.0f;
|
||||
|
||||
+116
-126
@@ -2,55 +2,35 @@
|
||||
|
||||
void command_feature(Client *c, const Seperator *sep)
|
||||
{
|
||||
// nested command aliasing
|
||||
std::string command = sep->arg[0] ? sep->arg[0] : "";
|
||||
bool is_size_alias = sep->arg[0] && Strings::Contains(command, "#size");
|
||||
bool is_nested_alias = (is_size_alias);
|
||||
const bool is_size_alias = sep->arg[0] && Strings::Contains(command, "#size");
|
||||
const bool is_nested_alias = is_size_alias;
|
||||
|
||||
int arguments = sep->argnum;
|
||||
const auto arguments = sep->argnum;
|
||||
if ((arguments < 2 || !sep->IsNumber(2)) && !is_nested_alias) {
|
||||
auto feature_save_link = Saylink::Silent("#npcedit featuresave");
|
||||
|
||||
c->Message(Chat::White, "Usage: #feature beard [Beard] - Change your or your target's Beard");
|
||||
c->Message(Chat::White, "Usage: #feature beardcolor [Beard Color] - Change your or your target's Beard Color");
|
||||
c->Message(Chat::White, "Usage: #feature details [Details] - Change your or your target's Drakkin Details");
|
||||
c->Message(Chat::White, "Usage: #feature eyes [Eye Color] - Change your or your target's Eyes");
|
||||
c->Message(Chat::White, "Usage: #feature face [Face] - Change your or your target's Face");
|
||||
c->Message(Chat::White, "Usage: #feature gender [Gender] - Change your or your target's Gender");
|
||||
c->Message(Chat::White, "Usage: #feature hair [Hair] - Change your or your target's Hair");
|
||||
c->Message(Chat::White, "Usage: #feature haircolor [Hair Color] - Change your or your target's Hair Color");
|
||||
c->Message(Chat::White, "Usage: #feature helm [Helmet Texture] - Change your or your target's Helmet Texture");
|
||||
c->Message(Chat::White, "Usage: #feature heritage [Heritage] - Change your or your target's Drakkin Heritage");
|
||||
c->Message(Chat::White, "Usage: #feature race [Race ID] - Change your or your target's Race");
|
||||
c->Message(Chat::White, "Usage: #feature size [Size] - Change your or your target's Size (Valid values are 0 to 255, decimal increments are allowed.)");
|
||||
c->Message(Chat::White, "Usage: #feature tattoo [Tattoo] - Change your or your target's Drakkin Tattoos");
|
||||
c->Message(Chat::White, "Usage: #feature texture [Texture] - Change your or your target's Texture");
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Note: All features are temporary. If your target is an NPC, you can save these features to the database using {}.",
|
||||
feature_save_link
|
||||
).c_str()
|
||||
);
|
||||
SendFeatureSubCommands(c);
|
||||
return;
|
||||
}
|
||||
|
||||
Mob* target = c->GetTarget() ? c->GetTarget() : c;
|
||||
Mob* t = c;
|
||||
if (c->GetTarget()) {
|
||||
t = c->GetTarget();
|
||||
}
|
||||
|
||||
bool is_beard = !strcasecmp(sep->arg[1], "beard");
|
||||
bool is_beard_color = !strcasecmp(sep->arg[1], "beardcolor");
|
||||
bool is_details = !strcasecmp(sep->arg[1], "details");
|
||||
bool is_eyes = !strcasecmp(sep->arg[1], "eyes");
|
||||
bool is_face = !strcasecmp(sep->arg[1], "face");
|
||||
bool is_gender = !strcasecmp(sep->arg[1], "gender");
|
||||
bool is_hair = !strcasecmp(sep->arg[1], "hair");
|
||||
bool is_hair_color = !strcasecmp(sep->arg[1], "haircolor");
|
||||
bool is_helm = !strcasecmp(sep->arg[1], "helm");
|
||||
bool is_heritage = !strcasecmp(sep->arg[1], "heritage");
|
||||
bool is_race = !strcasecmp(sep->arg[1], "race");
|
||||
bool is_size = !strcasecmp(sep->arg[1], "size") || is_size_alias;
|
||||
bool is_tattoo = !strcasecmp(sep->arg[1], "tattoo");
|
||||
bool is_texture = !strcasecmp(sep->arg[1], "texture");
|
||||
const bool is_beard = !strcasecmp(sep->arg[1], "beard");
|
||||
const bool is_beard_color = !strcasecmp(sep->arg[1], "beardcolor");
|
||||
const bool is_details = !strcasecmp(sep->arg[1], "details");
|
||||
const bool is_eyes = !strcasecmp(sep->arg[1], "eyes");
|
||||
const bool is_face = !strcasecmp(sep->arg[1], "face");
|
||||
const bool is_gender = !strcasecmp(sep->arg[1], "gender");
|
||||
const bool is_hair = !strcasecmp(sep->arg[1], "hair");
|
||||
const bool is_hair_color = !strcasecmp(sep->arg[1], "haircolor");
|
||||
const bool is_helm = !strcasecmp(sep->arg[1], "helm");
|
||||
const bool is_heritage = !strcasecmp(sep->arg[1], "heritage");
|
||||
const bool is_race = !strcasecmp(sep->arg[1], "race");
|
||||
const bool is_size = !strcasecmp(sep->arg[1], "size") || is_size_alias;
|
||||
const bool is_tattoo = !strcasecmp(sep->arg[1], "tattoo");
|
||||
const bool is_texture = !strcasecmp(sep->arg[1], "texture");
|
||||
|
||||
if (
|
||||
!is_beard &&
|
||||
@@ -68,103 +48,82 @@ void command_feature(Client *c, const Seperator *sep)
|
||||
!is_tattoo &&
|
||||
!is_texture
|
||||
) {
|
||||
auto feature_save_link = Saylink::Silent("#npcedit featuresave");
|
||||
|
||||
c->Message(Chat::White, "Usage: #feature beard [Beard] - Change your or your target's Beard");
|
||||
c->Message(Chat::White, "Usage: #feature beardcolor [Beard Color] - Change your or your target's Beard Color");
|
||||
c->Message(Chat::White, "Usage: #feature details [Details] - Change your or your target's Drakkin Details");
|
||||
c->Message(Chat::White, "Usage: #feature eyes [Eye Color] - Change your or your target's Eyes");
|
||||
c->Message(Chat::White, "Usage: #feature face [Face] - Change your or your target's Face");
|
||||
c->Message(Chat::White, "Usage: #feature gender [Gender] - Change your or your target's Gender");
|
||||
c->Message(Chat::White, "Usage: #feature hair [Hair] - Change your or your target's Hair");
|
||||
c->Message(Chat::White, "Usage: #feature haircolor [Hair Color] - Change your or your target's Hair Color");
|
||||
c->Message(Chat::White, "Usage: #feature helm [Helmet Texture] - Change your or your target's Helmet Texture");
|
||||
c->Message(Chat::White, "Usage: #feature heritage [Heritage] - Change your or your target's Drakkin Heritage");
|
||||
c->Message(Chat::White, "Usage: #feature race [Race ID] - Change your or your target's Race");
|
||||
c->Message(Chat::White, "Usage: #feature size [Size] - Change your or your target's Size (Valid values are 0 to 255, decimal increments are allowed.)");
|
||||
c->Message(Chat::White, "Usage: #feature tattoo [Tattoo] - Change your or your target's Drakkin Tattoos");
|
||||
c->Message(Chat::White, "Usage: #feature texture [Texture] - Change your or your target's Texture");
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Note: All features are temporary. If your target is an NPC, you can save these features to the database using {}.",
|
||||
feature_save_link
|
||||
).c_str()
|
||||
);
|
||||
SendFeatureSubCommands(c);
|
||||
return;
|
||||
}
|
||||
|
||||
FaceChange_Struct face{};
|
||||
face.haircolor = target->GetHairColor();
|
||||
face.beardcolor = target->GetBeardColor();
|
||||
face.eyecolor1 = target->GetEyeColor1();
|
||||
face.eyecolor2 = target->GetEyeColor2();
|
||||
face.hairstyle = target->GetHairStyle();
|
||||
face.face = target->GetLuclinFace();
|
||||
face.beard = target->GetBeard();
|
||||
face.drakkin_heritage = target->GetDrakkinHeritage();
|
||||
face.drakkin_tattoo = target->GetDrakkinTattoo();
|
||||
face.drakkin_details = target->GetDrakkinDetails();
|
||||
FaceChange_Struct f{
|
||||
.haircolor = t->GetHairColor(),
|
||||
.beardcolor = t->GetBeardColor(),
|
||||
.eyecolor1 = t->GetEyeColor1(),
|
||||
.eyecolor2 = t->GetEyeColor2(),
|
||||
.hairstyle = t->GetHairStyle(),
|
||||
.beard = t->GetBeard(),
|
||||
.face = t->GetLuclinFace(),
|
||||
.drakkin_heritage = t->GetDrakkinHeritage(),
|
||||
.drakkin_tattoo = t->GetDrakkinTattoo(),
|
||||
.drakkin_details = t->GetDrakkinDetails(),
|
||||
};
|
||||
|
||||
auto gender = target->GetGender();
|
||||
auto helm_texture = target->GetHelmTexture();
|
||||
auto race = target->GetModel();
|
||||
auto size = target->GetSize();
|
||||
auto texture = target->GetTexture();
|
||||
uint8 gender = t->GetGender();
|
||||
uint8 helm_texture = t->GetHelmTexture();
|
||||
uint16 race = t->GetModel();
|
||||
float size = t->GetSize();
|
||||
uint8 texture = t->GetTexture();
|
||||
|
||||
std::string feature_changed;
|
||||
float value_changed = 0.0f;
|
||||
|
||||
if (is_beard) {
|
||||
face.beard = static_cast<uint8>(Strings::ToUnsignedInt(sep->arg[2]));
|
||||
f.beard = static_cast<uint8>(Strings::ToUnsignedInt(sep->arg[2]));
|
||||
feature_changed = "Beard";
|
||||
value_changed = face.beard;
|
||||
value_changed = f.beard;
|
||||
} else if (is_beard_color) {
|
||||
face.beardcolor = static_cast<uint8>(Strings::ToUnsignedInt(sep->arg[2]));
|
||||
f.beardcolor = static_cast<uint8>(Strings::ToUnsignedInt(sep->arg[2]));
|
||||
feature_changed = "Beard Color";
|
||||
value_changed = face.beardcolor;
|
||||
value_changed = f.beardcolor;
|
||||
} else if (is_details) {
|
||||
if (target->GetRace() != DRAKKIN) {
|
||||
if (t->GetRace() != DRAKKIN) {
|
||||
c->Message(Chat::White, "You must target a Drakkin to use this command.");
|
||||
return;
|
||||
}
|
||||
|
||||
face.drakkin_details = static_cast<uint8>(Strings::ToUnsignedInt(sep->arg[2]));
|
||||
f.drakkin_details = static_cast<uint8>(Strings::ToUnsignedInt(sep->arg[2]));
|
||||
feature_changed = "Drakkin Details";
|
||||
value_changed = static_cast<float>(face.drakkin_details);
|
||||
value_changed = static_cast<float>(f.drakkin_details);
|
||||
} else if (is_eyes) {
|
||||
face.eyecolor1 = static_cast<uint8>(Strings::ToUnsignedInt(sep->arg[2]));
|
||||
f.eyecolor1 = static_cast<uint8>(Strings::ToUnsignedInt(sep->arg[2]));
|
||||
feature_changed = "Eyes";
|
||||
value_changed = face.eyecolor1; // eyecolor2 isn't used
|
||||
value_changed = f.eyecolor1; // eyecolor2 isn't used
|
||||
} else if (is_face) {
|
||||
face.face = static_cast<uint8>(Strings::ToUnsignedInt(sep->arg[2]));
|
||||
f.face = static_cast<uint8>(Strings::ToUnsignedInt(sep->arg[2]));
|
||||
feature_changed = "Face";
|
||||
value_changed = face.face;
|
||||
value_changed = f.face;
|
||||
} else if (is_gender) {
|
||||
gender = static_cast<uint8>(Strings::ToUnsignedInt(sep->arg[2]));
|
||||
feature_changed = "Gender";
|
||||
value_changed = gender;
|
||||
} else if (is_hair) {
|
||||
face.hairstyle = static_cast<uint8>(Strings::ToUnsignedInt(sep->arg[2]));
|
||||
f.hairstyle = static_cast<uint8>(Strings::ToUnsignedInt(sep->arg[2]));
|
||||
feature_changed = "Hair";
|
||||
value_changed = face.hairstyle;
|
||||
value_changed = f.hairstyle;
|
||||
} else if (is_hair_color) {
|
||||
face.haircolor = static_cast<uint8>(Strings::ToUnsignedInt(sep->arg[2]));
|
||||
f.haircolor = static_cast<uint8>(Strings::ToUnsignedInt(sep->arg[2]));
|
||||
feature_changed = "Hair Color";
|
||||
value_changed = face.haircolor;
|
||||
value_changed = f.haircolor;
|
||||
} else if (is_helm) {
|
||||
helm_texture = static_cast<uint8>(Strings::ToUnsignedInt(sep->arg[2]));
|
||||
feature_changed = "Helmet Texture";
|
||||
value_changed = helm_texture;
|
||||
} else if (is_heritage) {
|
||||
if (target->GetRace() != DRAKKIN) {
|
||||
if (t->GetRace() != DRAKKIN) {
|
||||
c->Message(Chat::White, "You must target a Drakkin to use this command.");
|
||||
return;
|
||||
}
|
||||
|
||||
face.drakkin_heritage = static_cast<uint8>(Strings::ToUnsignedInt(sep->arg[2]));
|
||||
f.drakkin_heritage = static_cast<uint8>(Strings::ToUnsignedInt(sep->arg[2]));
|
||||
feature_changed = "Drakkin Heritage";
|
||||
value_changed = static_cast<float>(face.drakkin_heritage);
|
||||
value_changed = static_cast<float>(f.drakkin_heritage);
|
||||
} else if (is_race) {
|
||||
race = static_cast<uint16>(Strings::ToUnsignedInt(sep->arg[2]));
|
||||
feature_changed = "Race";
|
||||
@@ -189,14 +148,14 @@ void command_feature(Client *c, const Seperator *sep)
|
||||
feature_changed = "Size";
|
||||
value_changed = size;
|
||||
} else if (is_tattoo) {
|
||||
if (target->GetRace() != DRAKKIN) {
|
||||
if (t->GetRace() != DRAKKIN) {
|
||||
c->Message(Chat::White, "You must target a Drakkin to use this command.");
|
||||
return;
|
||||
}
|
||||
|
||||
face.drakkin_tattoo = static_cast<uint8>(Strings::ToUnsignedInt(sep->arg[2]));
|
||||
f.drakkin_tattoo = static_cast<uint8>(Strings::ToUnsignedInt(sep->arg[2]));
|
||||
feature_changed = "Drakkin Tattoos";
|
||||
value_changed = static_cast<float>(face.drakkin_tattoo);
|
||||
value_changed = static_cast<float>(f.drakkin_tattoo);
|
||||
} else if (is_texture) {
|
||||
texture = static_cast<uint8>(Strings::ToUnsignedInt(sep->arg[2]));
|
||||
feature_changed = "Texture";
|
||||
@@ -206,29 +165,34 @@ void command_feature(Client *c, const Seperator *sep)
|
||||
// For now face number is not set through SetFace. This is because the
|
||||
// client may not update face features after being set to an invalid face
|
||||
// until a specific valid face number is re-sent (needs more research)
|
||||
if (!is_gender && !is_helm && !is_race && !is_size && !is_texture && !is_face)
|
||||
{
|
||||
target->SetFaceAppearance(face);
|
||||
}
|
||||
else
|
||||
{
|
||||
target->SendIllusionPacket(
|
||||
race,
|
||||
gender,
|
||||
texture,
|
||||
helm_texture,
|
||||
face.haircolor,
|
||||
face.beardcolor,
|
||||
target->GetEyeColor1(),
|
||||
target->GetEyeColor2(),
|
||||
face.hairstyle,
|
||||
face.face,
|
||||
face.beard,
|
||||
0xFF,
|
||||
face.drakkin_heritage,
|
||||
face.drakkin_tattoo,
|
||||
face.drakkin_details,
|
||||
size
|
||||
if (
|
||||
!is_face &&
|
||||
!is_gender &&
|
||||
!is_helm &&
|
||||
!is_race &&
|
||||
!is_size &&
|
||||
!is_texture
|
||||
) {
|
||||
t->SetFaceAppearance(f);
|
||||
} else {
|
||||
t->SendIllusionPacket(
|
||||
AppearanceStruct{
|
||||
.beard = f.beard,
|
||||
.beard_color = f.beardcolor,
|
||||
.drakkin_details = f.drakkin_details,
|
||||
.drakkin_heritage = f.drakkin_heritage,
|
||||
.drakkin_tattoo = f.drakkin_tattoo,
|
||||
.eye_color_one = t->GetEyeColor1(),
|
||||
.eye_color_two = t->GetEyeColor2(),
|
||||
.face = f.face,
|
||||
.gender_id = gender,
|
||||
.hair = f.hairstyle,
|
||||
.hair_color = f.haircolor,
|
||||
.helmet_texture = helm_texture,
|
||||
.race_id = race,
|
||||
.size = size,
|
||||
.texture = texture,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -237,7 +201,7 @@ void command_feature(Client *c, const Seperator *sep)
|
||||
fmt::format(
|
||||
"{} set for {} to {}.",
|
||||
feature_changed,
|
||||
c->GetTargetDescription(target),
|
||||
c->GetTargetDescription(t),
|
||||
(
|
||||
is_size ?
|
||||
fmt::format(
|
||||
@@ -253,3 +217,29 @@ void command_feature(Client *c, const Seperator *sep)
|
||||
);
|
||||
}
|
||||
|
||||
void SendFeatureSubCommands(Client *c)
|
||||
{
|
||||
const std::string& feature_save_link = Saylink::Silent("#npcedit featuresave");
|
||||
|
||||
c->Message(Chat::White, "Usage: #feature beard [Beard] - Change your or your target's Beard");
|
||||
c->Message(Chat::White, "Usage: #feature beardcolor [Beard Color] - Change your or your target's Beard Color");
|
||||
c->Message(Chat::White, "Usage: #feature details [Details] - Change your or your target's Drakkin Details");
|
||||
c->Message(Chat::White, "Usage: #feature eyes [Eye Color] - Change your or your target's Eyes");
|
||||
c->Message(Chat::White, "Usage: #feature face [Face] - Change your or your target's Face");
|
||||
c->Message(Chat::White, "Usage: #feature gender [Gender] - Change your or your target's Gender");
|
||||
c->Message(Chat::White, "Usage: #feature hair [Hair] - Change your or your target's Hair");
|
||||
c->Message(Chat::White, "Usage: #feature haircolor [Hair Color] - Change your or your target's Hair Color");
|
||||
c->Message(Chat::White, "Usage: #feature helm [Helmet Texture] - Change your or your target's Helmet Texture");
|
||||
c->Message(Chat::White, "Usage: #feature heritage [Heritage] - Change your or your target's Drakkin Heritage");
|
||||
c->Message(Chat::White, "Usage: #feature race [Race ID] - Change your or your target's Race");
|
||||
c->Message(Chat::White, "Usage: #feature size [Size] - Change your or your target's Size (Valid values are 0 to 255, decimal increments are allowed.)");
|
||||
c->Message(Chat::White, "Usage: #feature tattoo [Tattoo] - Change your or your target's Drakkin Tattoos");
|
||||
c->Message(Chat::White, "Usage: #feature texture [Texture] - Change your or your target's Texture");
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Note: All features are temporary. If your target is an NPC, you can save these features to the database using {}.",
|
||||
feature_save_link
|
||||
).c_str()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ void FindAA(Client *c, const Seperator *sep)
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"AA {} | {}",
|
||||
Strings::Commify(aa_id),
|
||||
aa_id,
|
||||
aa_name
|
||||
).c_str()
|
||||
);
|
||||
@@ -22,7 +22,7 @@ void FindAA(Client *c, const Seperator *sep)
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"AA ID {} was not found.",
|
||||
Strings::Commify(aa_id)
|
||||
aa_id
|
||||
).c_str()
|
||||
);
|
||||
|
||||
@@ -51,7 +51,7 @@ void FindAA(Client *c, const Seperator *sep)
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"AA {} | {}",
|
||||
Strings::Commify(a.first),
|
||||
a.first,
|
||||
aa_name
|
||||
).c_str()
|
||||
);
|
||||
|
||||
@@ -12,7 +12,7 @@ void FindCharacter(Client *c, const Seperator *sep)
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Character ID {} does not exist or is invalid.",
|
||||
Strings::Commify(character_id)
|
||||
character_id
|
||||
).c_str()
|
||||
);
|
||||
|
||||
@@ -23,7 +23,7 @@ void FindCharacter(Client *c, const Seperator *sep)
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Character ID {} | {}",
|
||||
Strings::Commify(character_id),
|
||||
character_id,
|
||||
e.name
|
||||
).c_str()
|
||||
);
|
||||
|
||||
@@ -13,7 +13,7 @@ void FindCurrency(Client *c, const Seperator *sep)
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"There is no currency with an item ID of {}.",
|
||||
Strings::Commify(item_id)
|
||||
item_id
|
||||
).c_str()
|
||||
);
|
||||
|
||||
@@ -26,7 +26,7 @@ void FindCurrency(Client *c, const Seperator *sep)
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Item ID {} does not exist.",
|
||||
Strings::Commify(item_id)
|
||||
item_id
|
||||
).c_str()
|
||||
);
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ void FindFaction(Client *c, const Seperator *sep)
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Faction {} | {}",
|
||||
Strings::Commify(faction_id),
|
||||
faction_id,
|
||||
faction_name
|
||||
).c_str()
|
||||
);
|
||||
@@ -22,7 +22,7 @@ void FindFaction(Client *c, const Seperator *sep)
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Faction ID {} was not found.",
|
||||
Strings::Commify(faction_id)
|
||||
faction_id
|
||||
).c_str()
|
||||
);
|
||||
|
||||
@@ -48,7 +48,7 @@ void FindFaction(Client *c, const Seperator *sep)
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Faction {} | {}",
|
||||
Strings::Commify(faction_id),
|
||||
faction_id,
|
||||
faction_name
|
||||
).c_str()
|
||||
);
|
||||
|
||||
@@ -104,7 +104,7 @@ void FindItem(Client *c, const Seperator *sep)
|
||||
"{} | {} ({})",
|
||||
summon_links,
|
||||
database.CreateItemLink(e),
|
||||
Strings::Commify(item->ID)
|
||||
item->ID
|
||||
).c_str()
|
||||
);
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ void FindNPCType(Client *c, const Seperator *sep)
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"NPC {} | {}{}",
|
||||
Strings::Commify(row[0]),
|
||||
row[0],
|
||||
row[1],
|
||||
(
|
||||
can_spawn_npcs ?
|
||||
|
||||
@@ -19,7 +19,7 @@ void FindRecipe(Client *c, const Seperator *sep)
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Recipe ID {} could not be found.",
|
||||
Strings::Commify(recipe_id)
|
||||
recipe_id
|
||||
).c_str()
|
||||
);
|
||||
return;
|
||||
@@ -29,7 +29,7 @@ void FindRecipe(Client *c, const Seperator *sep)
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Recipe {} | {}{}",
|
||||
Strings::Commify(recipe_id),
|
||||
recipe_id,
|
||||
l[0].name,
|
||||
(
|
||||
can_view_recipes ?
|
||||
|
||||
@@ -16,7 +16,7 @@ void FindSpell(Client *c, const Seperator *sep)
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Spell ID {} was not found.",
|
||||
Strings::Commify(spell_id)
|
||||
spell_id
|
||||
).c_str()
|
||||
);
|
||||
|
||||
@@ -27,7 +27,7 @@ void FindSpell(Client *c, const Seperator *sep)
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Spell {} | {}",
|
||||
Strings::Commify(spell_id),
|
||||
spell_id,
|
||||
spells[spell_id].name
|
||||
).c_str()
|
||||
);
|
||||
@@ -53,7 +53,7 @@ void FindSpell(Client *c, const Seperator *sep)
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Spell {} | {}{}",
|
||||
Strings::Commify(spell_id),
|
||||
spell_id,
|
||||
spell_name,
|
||||
(
|
||||
can_cast_spells ?
|
||||
|
||||
@@ -18,7 +18,7 @@ void FindTask(Client *c, const Seperator *sep)
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Task ID {} was not found.",
|
||||
Strings::Commify(task_id)
|
||||
task_id
|
||||
).c_str()
|
||||
);
|
||||
|
||||
@@ -29,7 +29,7 @@ void FindTask(Client *c, const Seperator *sep)
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Task {} | {}",
|
||||
Strings::Commify(task_id),
|
||||
task_id,
|
||||
task_name
|
||||
).c_str()
|
||||
);
|
||||
@@ -52,7 +52,7 @@ void FindTask(Client *c, const Seperator *sep)
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Task {} | {}{}",
|
||||
Strings::Commify(t.first),
|
||||
t.first,
|
||||
task_name,
|
||||
(
|
||||
can_assign_tasks ?
|
||||
|
||||
@@ -60,11 +60,11 @@ void command_fixmob(Client *c, const Seperator *sep)
|
||||
ChangeSetting = Race;
|
||||
}
|
||||
else if (strcasecmp(command, "gender") == 0) {
|
||||
if (Gender == 0 && codeMove == 'p') {
|
||||
Gender = 2;
|
||||
if (Gender == MALE && codeMove == 'p') {
|
||||
Gender = NEUTER;
|
||||
}
|
||||
else if (Gender >= 2 && codeMove != 'p') {
|
||||
Gender = 0;
|
||||
else if (Gender >= NEUTER && codeMove != 'p') {
|
||||
Gender = MALE;
|
||||
}
|
||||
else {
|
||||
Gender += Adjustment;
|
||||
@@ -238,9 +238,22 @@ void command_fixmob(Client *c, const Seperator *sep)
|
||||
}
|
||||
else {
|
||||
target->SendIllusionPacket(
|
||||
Race, Gender, Texture, HelmTexture, HairColor, BeardColor,
|
||||
EyeColor1, EyeColor2, HairStyle, LuclinFace, Beard, 0xFF,
|
||||
DrakkinHeritage, DrakkinTattoo, DrakkinDetails
|
||||
AppearanceStruct{
|
||||
.beard = Beard,
|
||||
.beard_color = BeardColor,
|
||||
.drakkin_details = DrakkinDetails,
|
||||
.drakkin_heritage = DrakkinHeritage,
|
||||
.drakkin_tattoo = DrakkinTattoo,
|
||||
.eye_color_one = EyeColor1,
|
||||
.eye_color_two = EyeColor2,
|
||||
.face = LuclinFace,
|
||||
.gender_id = Gender,
|
||||
.hair = HairStyle,
|
||||
.hair_color = HairColor,
|
||||
.helmet_texture = HelmTexture,
|
||||
.race_id = Race,
|
||||
.texture = Texture,
|
||||
}
|
||||
);
|
||||
|
||||
c->Message(Chat::White, "%s=%i", ChangeType, ChangeSetting);
|
||||
|
||||
@@ -25,7 +25,7 @@ void command_npcedit(Client *c, const Seperator *sep)
|
||||
auto npc_id = t->GetNPCTypeID();
|
||||
auto npc_id_string = fmt::format(
|
||||
"NPC ID {}",
|
||||
Strings::Commify(std::to_string(npc_id))
|
||||
npc_id
|
||||
);
|
||||
|
||||
auto n = NpcTypesRepository::FindOne(content_db, npc_id);
|
||||
|
||||
@@ -18,6 +18,7 @@ void command_reload(Client *c, const Seperator *sep)
|
||||
bool is_blocked_spells = !strcasecmp(sep->arg[1], "blocked_spells");
|
||||
bool is_commands = !strcasecmp(sep->arg[1], "commands");
|
||||
bool is_content_flags = !strcasecmp(sep->arg[1], "content_flags");
|
||||
bool is_data_buckets = !strcasecmp(sep->arg[1], "data_buckets_cache");
|
||||
bool is_doors = !strcasecmp(sep->arg[1], "doors");
|
||||
bool is_dztemplates = !strcasecmp(sep->arg[1], "dztemplates");
|
||||
bool is_ground_spawns = !strcasecmp(sep->arg[1], "ground_spawns");
|
||||
@@ -46,6 +47,7 @@ void command_reload(Client *c, const Seperator *sep)
|
||||
!is_blocked_spells &&
|
||||
!is_commands &&
|
||||
!is_content_flags &&
|
||||
!is_data_buckets &&
|
||||
!is_doors &&
|
||||
!is_dztemplates &&
|
||||
!is_ground_spawns &&
|
||||
@@ -92,6 +94,9 @@ void command_reload(Client *c, const Seperator *sep)
|
||||
} else if (is_doors) {
|
||||
c->Message(Chat::White, "Attempting to reload Doors globally.");
|
||||
pack = new ServerPacket(ServerOP_ReloadDoors, 0);
|
||||
} else if (is_data_buckets) {
|
||||
c->Message(Chat::White, "Attempting to flush data buckets cache globally.");
|
||||
pack = new ServerPacket(ServerOP_ReloadDataBucketsCache, 0);
|
||||
} else if (is_dztemplates) {
|
||||
c->Message(Chat::White, "Attempting to reload Dynamic Zone Templates globally.");
|
||||
pack = new ServerPacket(ServerOP_ReloadDzTemplates, 0);
|
||||
@@ -225,74 +230,8 @@ void command_reload(Client *c, const Seperator *sep)
|
||||
auto RW = (ReloadWorld_Struct *) pack->pBuffer;
|
||||
RW->global_repop = global_repop;
|
||||
} else if (is_zone) {
|
||||
zone_store.LoadZones(content_db);
|
||||
|
||||
if (arguments < 2) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Zone Header Load {} | Zone: {}",
|
||||
(
|
||||
zone->LoadZoneCFG(zone->GetShortName(), zone->GetInstanceVersion()) ?
|
||||
"Succeeded" :
|
||||
"Failed"
|
||||
),
|
||||
zone->GetZoneDescription()
|
||||
).c_str()
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
auto zone_id = (
|
||||
sep->IsNumber(2) ?
|
||||
Strings::ToUnsignedInt(sep->arg[2]) :
|
||||
ZoneID(sep->arg[2])
|
||||
);
|
||||
if (!zone_id) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Zone ID {} could not be found.",
|
||||
zone_id
|
||||
).c_str()
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
auto zone_short_name = ZoneName(zone_id);
|
||||
auto zone_long_name = ZoneLongName(zone_id);
|
||||
auto version = (
|
||||
sep->IsNumber(3) ?
|
||||
Strings::ToUnsignedInt(sep->arg[3]) :
|
||||
0
|
||||
);
|
||||
|
||||
auto outapp = new EQApplicationPacket(OP_NewZone, sizeof(NewZone_Struct));
|
||||
memcpy(outapp->pBuffer, &zone->newzone_data, outapp->size);
|
||||
entity_list.QueueClients(c, outapp);
|
||||
safe_delete(outapp);
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Zone Header Load {} | Zone: {} ({}){}",
|
||||
(
|
||||
zone->LoadZoneCFG(zone_short_name, version) ?
|
||||
"Succeeded" :
|
||||
"Failed"
|
||||
),
|
||||
zone_long_name,
|
||||
zone_short_name,
|
||||
(
|
||||
version ?
|
||||
fmt::format(
|
||||
" Version: {}",
|
||||
version
|
||||
) :
|
||||
""
|
||||
)
|
||||
).c_str()
|
||||
);
|
||||
c->Message(Chat::White, "Attempting to reloading Zone data globally.");
|
||||
pack = new ServerPacket(ServerOP_ReloadZoneData, sizeof(NewZone_Struct));
|
||||
} else if (is_zone_points) {
|
||||
c->Message(Chat::White, "Attempting to reloading Zone Points globally.");
|
||||
pack = new ServerPacket(ServerOP_ReloadZonePoints, 0);
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "set/loginserver_info.cpp"
|
||||
#include "set/mana.cpp"
|
||||
#include "set/mana_full.cpp"
|
||||
#include "set/motd.cpp"
|
||||
#include "set/name.cpp"
|
||||
#include "set/ooc_mute.cpp"
|
||||
#include "set/password.cpp"
|
||||
@@ -82,7 +83,7 @@ void command_set(Client *c, const Seperator *sep)
|
||||
Cmd{.cmd = "frozen", .u = "frozen [on|off]", .fn = SetFrozen, .a = {"#freeze", "#unfreeze"}},
|
||||
Cmd{.cmd = "gender", .u = "gender [Gender ID]", .fn = SetGender, .a = {"#gender"}},
|
||||
Cmd{.cmd = "gender_permanent", .u = "gender_permanent [Gender ID]", .fn = SetGenderPermanent, .a = {"#permagender"}},
|
||||
Cmd{.cmd = "gm", .u = "gm [on|off]", .fn = SetGM, .a = {"#flymode"}},
|
||||
Cmd{.cmd = "gm", .u = "gm [on|off]", .fn = SetGM, .a = {"#gm"}},
|
||||
Cmd{.cmd = "gm_speed", .u = "gm_speed [on|off]", .fn = SetGMSpeed, .a = {"#gmspeed"}},
|
||||
Cmd{.cmd = "gm_status", .u = "gm_status [GM Status] [Account]", .fn = SetGMStatus, .a = {"#flag"}},
|
||||
Cmd{.cmd = "god_mode", .u = "god_mode [on|off]", .fn = SetGodMode, .a = {"#godmode"}},
|
||||
@@ -98,6 +99,7 @@ void command_set(Client *c, const Seperator *sep)
|
||||
Cmd{.cmd = "loginserver_info", .u = "loginserver_info [Email] [Password]", .fn = SetLoginserverInfo, .a = {"#setlsinfo"}},
|
||||
Cmd{.cmd = "mana", .u = "mana [Amount]", .fn = SetMana, .a = {"#setmana"}},
|
||||
Cmd{.cmd = "mana_full", .u = "mana_full", .fn = SetManaFull, .a = {"#mana"}},
|
||||
Cmd{.cmd = "motd", .u = "motd", .fn = SetMOTD, .a = {"#motd"}},
|
||||
Cmd{.cmd = "name", .u = "name", .fn = SetName, .a = {"#name"}},
|
||||
Cmd{.cmd = "ooc_mute", .u = "ooc_mute", .fn = SetOOCMute, .a = {"#oocmute"}},
|
||||
Cmd{.cmd = "password", .u = "password [Account Name] [Password] (account table password)", .fn = SetPassword, .a = {"#setpass"}},
|
||||
|
||||
@@ -22,8 +22,11 @@ void SetGender(Client *c, const Seperator *sep)
|
||||
}
|
||||
|
||||
t->SendIllusionPacket(
|
||||
t->GetRace(),
|
||||
gender_id
|
||||
AppearanceStruct{
|
||||
.gender_id = gender_id,
|
||||
.race_id = t->GetRace(),
|
||||
.size = t->GetSize(),
|
||||
}
|
||||
);
|
||||
|
||||
c->Message(
|
||||
|
||||
@@ -30,7 +30,13 @@ void SetGenderPermanent(Client *c, const Seperator *sep)
|
||||
|
||||
t->SetBaseGender(gender_id);
|
||||
t->Save();
|
||||
t->SendIllusionPacket(t->GetRace(), gender_id);
|
||||
t->SendIllusionPacket(
|
||||
AppearanceStruct{
|
||||
.gender_id = gender_id,
|
||||
.race_id = t->GetRace(),
|
||||
.size = t->GetSize(),
|
||||
}
|
||||
);
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
extern WorldServer worldserver;
|
||||
|
||||
void command_motd(Client *c, const Seperator *sep)
|
||||
void SetMOTD(Client *c, const Seperator *sep)
|
||||
{
|
||||
const auto arguments = sep->argnum;
|
||||
if (arguments < 2) {
|
||||
|
||||
@@ -37,7 +37,12 @@ void SetRace(Client *c, const Seperator *sep)
|
||||
return;
|
||||
}
|
||||
|
||||
t->SendIllusionPacket(race_id);
|
||||
t->SendIllusionPacket(
|
||||
AppearanceStruct{
|
||||
.race_id = race_id,
|
||||
.size = t->GetSize(),
|
||||
}
|
||||
);
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
|
||||
@@ -31,7 +31,13 @@ void SetRacePermanent(Client *c, const Seperator *sep)
|
||||
t->SetBaseRace(race_id);
|
||||
t->SetBaseGender(gender_id);
|
||||
t->Save();
|
||||
t->SendIllusionPacket(race_id, gender_id);
|
||||
t->SendIllusionPacket(
|
||||
AppearanceStruct{
|
||||
.gender_id = gender_id,
|
||||
.race_id = race_id,
|
||||
.size = t->GetSize()
|
||||
}
|
||||
);
|
||||
|
||||
c->Message(
|
||||
Chat::White,
|
||||
|
||||
@@ -8,8 +8,8 @@ void SetTexture(Client *c, const Seperator *sep)
|
||||
return;
|
||||
}
|
||||
|
||||
const uint16 texture = Strings::ToUnsignedInt(sep->arg[2]);
|
||||
const uint8 helmet_texture = (
|
||||
const uint8 texture = Strings::ToUnsignedInt(sep->arg[2]);
|
||||
const uint8 helmet_texture = (
|
||||
sep->IsNumber(3) ?
|
||||
Strings::ToUnsignedInt(sep->arg[3]) :
|
||||
0
|
||||
@@ -30,10 +30,12 @@ void SetTexture(Client *c, const Seperator *sep)
|
||||
}
|
||||
} else { // Non-Player Races only need Illusion Packets to be sent for texture
|
||||
t->SendIllusionPacket(
|
||||
t->GetModel(),
|
||||
t->GetGender(),
|
||||
texture,
|
||||
helmet_texture
|
||||
AppearanceStruct{
|
||||
.gender_id = t->GetGender(),
|
||||
.helmet_texture = helmet_texture,
|
||||
.race_id = t->GetModel(),
|
||||
.texture = texture,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ void ShowGroupInfo(Client *c, const Seperator *sep)
|
||||
|
||||
popup_table += DialogueWindow::TableRow(
|
||||
DialogueWindow::TableCell("Group ID") +
|
||||
DialogueWindow::TableCell(Strings::Commify(g->GetID()))
|
||||
DialogueWindow::TableCell(std::to_string(g->GetID()))
|
||||
);
|
||||
|
||||
popup_table += DialogueWindow::TableRow(
|
||||
|
||||
@@ -27,7 +27,7 @@ void ShowRecipe(Client *c, const Seperator *sep)
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Recipe ID {} has no entries or could not be found.",
|
||||
Strings::Commify(recipe_id)
|
||||
recipe_id
|
||||
).c_str()
|
||||
);
|
||||
return;
|
||||
@@ -37,7 +37,7 @@ void ShowRecipe(Client *c, const Seperator *sep)
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"Recipe {} | {}",
|
||||
Strings::Commify(recipe_id),
|
||||
recipe_id,
|
||||
r[0].name
|
||||
).c_str()
|
||||
);
|
||||
|
||||
@@ -34,7 +34,7 @@ void ShowTimers(Client *c, const Seperator *sep)
|
||||
const uint32 remaining_time = e.second->GetRemainingTime();
|
||||
if (remaining_time) {
|
||||
popup_table += DialogueWindow::TableRow(
|
||||
DialogueWindow::TableCell(Strings::Commify(e.first)) +
|
||||
DialogueWindow::TableCell(std::to_string(e.first)) +
|
||||
DialogueWindow::TableCell(Strings::SecondsToTime(remaining_time))
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2,15 +2,7 @@
|
||||
|
||||
void ShowZoneLoot(Client *c, const Seperator *sep)
|
||||
{
|
||||
if (!sep->IsNumber(2)) {
|
||||
c->Message(
|
||||
Chat::White,
|
||||
"Usage: #show zone_loot [Item ID]"
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const uint32 search_item_id = Strings::ToUnsignedInt(sep->arg[2]);
|
||||
const uint32 search_item_id = sep->IsNumber(2) ? Strings::ToUnsignedInt(sep->arg[2]) : 0;
|
||||
|
||||
std::vector<std::pair<NPC *, ItemList>> v;
|
||||
|
||||
@@ -44,7 +36,7 @@ void ShowZoneLoot(Client *c, const Seperator *sep)
|
||||
);
|
||||
|
||||
npc_link = fmt::format(
|
||||
"NPC: {} (ID {}) [{}]",
|
||||
"{} (ID {}) | {}",
|
||||
n->GetCleanName(),
|
||||
n->GetID(),
|
||||
command_link
|
||||
@@ -60,11 +52,32 @@ void ShowZoneLoot(Client *c, const Seperator *sep)
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"{}. {} ({}) {}",
|
||||
"Item {} | {}{}{}",
|
||||
loot_number,
|
||||
linker.GenerateLink(),
|
||||
Strings::Commify(i->item_id),
|
||||
npc_link
|
||||
(
|
||||
!search_item_id ?
|
||||
fmt::format(
|
||||
"{} ({}) | ",
|
||||
linker.GenerateLink(),
|
||||
i->item_id
|
||||
) :
|
||||
""
|
||||
),
|
||||
npc_link,
|
||||
(
|
||||
!search_item_id ?
|
||||
fmt::format(
|
||||
" | {}",
|
||||
Saylink::Silent(
|
||||
fmt::format(
|
||||
"#show zone_loot {}",
|
||||
i->item_id
|
||||
),
|
||||
"Show"
|
||||
)
|
||||
) :
|
||||
""
|
||||
)
|
||||
).c_str()
|
||||
);
|
||||
|
||||
@@ -81,7 +94,7 @@ void ShowZoneLoot(Client *c, const Seperator *sep)
|
||||
fmt::format(
|
||||
"{} ({}) is dropping in {} place{}.",
|
||||
database.CreateItemLink(search_item_id),
|
||||
Strings::Commify(search_item_id),
|
||||
search_item_id,
|
||||
loot_count,
|
||||
loot_count != 1 ? "s" : ""
|
||||
).c_str()
|
||||
@@ -93,7 +106,7 @@ void ShowZoneLoot(Client *c, const Seperator *sep)
|
||||
c->Message(
|
||||
Chat::White,
|
||||
fmt::format(
|
||||
"{} Item {} {} dropping.",
|
||||
"{} Item{} {} dropping.",
|
||||
loot_count,
|
||||
loot_count != 1 ? "s" : "",
|
||||
loot_count != 1 ? "are" : "is"
|
||||
|
||||
@@ -63,8 +63,8 @@ void command_spawneditmass(Client *c, const Seperator *sep)
|
||||
Chat::Yellow,
|
||||
fmt::format(
|
||||
"Spawn2 ID: {} NPC ID: {} Name: {} Respawn Time: {} ({})",
|
||||
Strings::Commify(spawn2_id),
|
||||
Strings::Commify(npc_id),
|
||||
spawn2_id,
|
||||
npc_id,
|
||||
npc_name,
|
||||
Strings::SecondsToTime(Strings::ToInt(respawn_time)),
|
||||
Strings::Commify(respawn_time)
|
||||
|
||||
+4
-2
@@ -714,8 +714,9 @@ void HateList::PrintHateListToClient(Client *c)
|
||||
|
||||
int HateList::AreaRampage(Mob *caster, Mob *target, int count, ExtraAttackOptions *opts)
|
||||
{
|
||||
if (!target || !caster)
|
||||
if (!target || !caster) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// tank will be hit ONLY if they are the only target on the hate list
|
||||
// if there is anyone else on the hate list, the tank will not be hit, even if those others aren't hit either
|
||||
@@ -730,9 +731,10 @@ int HateList::AreaRampage(Mob *caster, Mob *target, int count, ExtraAttackOption
|
||||
std::vector<uint16> id_list;
|
||||
for (auto &h : list) {
|
||||
if (h->entity_on_hatelist && h->entity_on_hatelist != caster && h->entity_on_hatelist != target &&
|
||||
caster->CombatRange(h->entity_on_hatelist, 1.0, true)) {
|
||||
caster->CombatRange(h->entity_on_hatelist, 1.0, true, opts)) {
|
||||
id_list.push_back(h->entity_on_hatelist->GetID());
|
||||
}
|
||||
|
||||
if (count != -1 && id_list.size() > count) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -641,9 +641,7 @@ Lua_Mob_List Lua_EntityList::GetCloseMobList(Lua_Mob mob) {
|
||||
Lua_Mob_List ret;
|
||||
|
||||
const auto& l = self->GetCloseMobList(mob);
|
||||
|
||||
ret.entries.reserve(l.size());
|
||||
|
||||
for (const auto& e : l) {
|
||||
ret.entries.emplace_back(Lua_Mob(e.second));
|
||||
}
|
||||
@@ -653,14 +651,9 @@ Lua_Mob_List Lua_EntityList::GetCloseMobList(Lua_Mob mob) {
|
||||
|
||||
Lua_Mob_List Lua_EntityList::GetCloseMobList(Lua_Mob mob, float distance) {
|
||||
Lua_Safe_Call_Class(Lua_Mob_List);
|
||||
|
||||
Lua_Mob_List ret;
|
||||
|
||||
const auto& l = self->GetCloseMobList(mob);
|
||||
|
||||
ret.entries.reserve(l.size());
|
||||
|
||||
for (const auto& e : l) {
|
||||
for (const auto& e : self->GetCloseMobList(mob)) {
|
||||
if (mob.CalculateDistance(e.second) <= distance) {
|
||||
ret.entries.emplace_back(Lua_Mob(e.second));
|
||||
}
|
||||
@@ -674,11 +667,7 @@ Lua_Mob_List Lua_EntityList::GetCloseMobList(Lua_Mob mob, float distance, bool i
|
||||
|
||||
Lua_Mob_List ret;
|
||||
|
||||
const auto& l = self->GetCloseMobList(mob);
|
||||
|
||||
ret.entries.reserve(l.size());
|
||||
|
||||
for (const auto& e : l) {
|
||||
for (const auto& e : self->GetCloseMobList(mob)) {
|
||||
if (ignore_self && e.second == mob) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1812,6 +1812,7 @@ bool lua_is_content_flag_enabled(std::string content_flag){
|
||||
|
||||
void lua_set_content_flag(std::string flag_name, bool enabled){
|
||||
content_service.SetContentFlag(flag_name, enabled);
|
||||
zone->ReloadContentFlags();
|
||||
}
|
||||
|
||||
Lua_Expedition lua_get_expedition() {
|
||||
|
||||
+43
-27
@@ -1554,19 +1554,33 @@ void Lua_Mob::SetFlyMode(int in) {
|
||||
self->SetFlyMode(static_cast<GravityBehavior>(in));
|
||||
}
|
||||
|
||||
void Lua_Mob::SetTexture(int in) {
|
||||
void Lua_Mob::SetTexture(uint8 texture) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->SendIllusionPacket(self->GetRace(), 0xFF, in);
|
||||
self->SendIllusionPacket(
|
||||
AppearanceStruct{
|
||||
.race_id = self->GetRace(),
|
||||
.texture = texture
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void Lua_Mob::SetRace(int in) {
|
||||
void Lua_Mob::SetRace(uint16 race_id) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->SendIllusionPacket(in);
|
||||
self->SendIllusionPacket(
|
||||
AppearanceStruct{
|
||||
.race_id = race_id
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void Lua_Mob::SetGender(int in) {
|
||||
void Lua_Mob::SetGender(uint8 gender_id) {
|
||||
Lua_Safe_Call_Void();
|
||||
self->SendIllusionPacket(self->GetRace(), in);
|
||||
self->SendIllusionPacket(
|
||||
AppearanceStruct{
|
||||
.gender_id = gender_id,
|
||||
.race_id = self->GetRace(),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void Lua_Mob::SendIllusionPacket(luabind::adl::object illusion) {
|
||||
@@ -1740,24 +1754,26 @@ void Lua_Mob::SendIllusionPacket(luabind::adl::object illusion) {
|
||||
}
|
||||
|
||||
self->SendIllusionPacket(
|
||||
race,
|
||||
gender,
|
||||
texture,
|
||||
helmtexture,
|
||||
haircolor,
|
||||
beardcolor,
|
||||
eyecolor1,
|
||||
eyecolor2,
|
||||
hairstyle,
|
||||
luclinface,
|
||||
beard,
|
||||
aa_title,
|
||||
drakkin_heritage,
|
||||
drakkin_tattoo,
|
||||
drakkin_details,
|
||||
size,
|
||||
send_appearance_effects,
|
||||
target
|
||||
AppearanceStruct{
|
||||
.aa_title = aa_title,
|
||||
.beard = beard,
|
||||
.beard_color = beardcolor,
|
||||
.drakkin_details = drakkin_details,
|
||||
.drakkin_heritage = drakkin_heritage,
|
||||
.drakkin_tattoo = drakkin_tattoo,
|
||||
.eye_color_one = eyecolor1,
|
||||
.eye_color_two = eyecolor2,
|
||||
.face = luclinface,
|
||||
.gender_id = gender,
|
||||
.hair = hairstyle,
|
||||
.hair_color = haircolor,
|
||||
.helmet_texture = helmtexture,
|
||||
.race_id = race,
|
||||
.send_effects = send_appearance_effects,
|
||||
.size = size,
|
||||
.target = target,
|
||||
.texture = texture,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3605,7 +3621,7 @@ luabind::scope lua_register_mob() {
|
||||
.def("SetExtraHaste", (void(Lua_Mob::*)(int))&Lua_Mob::SetExtraHaste)
|
||||
.def("SetFlurryChance", (void(Lua_Mob::*)(int))&Lua_Mob::SetFlurryChance)
|
||||
.def("SetFlyMode", (void(Lua_Mob::*)(int))&Lua_Mob::SetFlyMode)
|
||||
.def("SetGender", (void(Lua_Mob::*)(int))&Lua_Mob::SetGender)
|
||||
.def("SetGender", (void(Lua_Mob::*)(uint8))&Lua_Mob::SetGender)
|
||||
.def("SetGlobal", (void(Lua_Mob::*)(const char*,const char*,int,const char*))&Lua_Mob::SetGlobal)
|
||||
.def("SetGlobal", (void(Lua_Mob::*)(const char*,const char*,int,const char*,Lua_Mob))&Lua_Mob::SetGlobal)
|
||||
.def("SetHP", &Lua_Mob::SetHP)
|
||||
@@ -3622,14 +3638,14 @@ luabind::scope lua_register_mob() {
|
||||
.def("SetPet", &Lua_Mob::SetPet)
|
||||
.def("SetPetOrder", (void(Lua_Mob::*)(int))&Lua_Mob::SetPetOrder)
|
||||
.def("SetPseudoRoot", (void(Lua_Mob::*)(bool))&Lua_Mob::SetPseudoRoot)
|
||||
.def("SetRace", (void(Lua_Mob::*)(int))&Lua_Mob::SetRace)
|
||||
.def("SetRace", (void(Lua_Mob::*)(uint16))&Lua_Mob::SetRace)
|
||||
.def("SetRunning", (void(Lua_Mob::*)(bool))&Lua_Mob::SetRunning)
|
||||
.def("SetSlotTint", (void(Lua_Mob::*)(int,int,int,int))&Lua_Mob::SetSlotTint)
|
||||
.def("SetSpecialAbility", (void(Lua_Mob::*)(int,int))&Lua_Mob::SetSpecialAbility)
|
||||
.def("SetSpecialAbilityParam", (void(Lua_Mob::*)(int,int,int))&Lua_Mob::SetSpecialAbilityParam)
|
||||
.def("SetTarget", &Lua_Mob::SetTarget)
|
||||
.def("SetTargetable", (void(Lua_Mob::*)(bool))&Lua_Mob::SetTargetable)
|
||||
.def("SetTexture", (void(Lua_Mob::*)(int))&Lua_Mob::SetTexture)
|
||||
.def("SetTexture", (void(Lua_Mob::*)(uint8))&Lua_Mob::SetTexture)
|
||||
.def("SetTimer", &Lua_Mob::SetTimer)
|
||||
.def("SetTimerMS", &Lua_Mob::SetTimerMS)
|
||||
.def("StopAllTimers", &Lua_Mob::StopAllTimers)
|
||||
|
||||
+3
-3
@@ -351,9 +351,9 @@ public:
|
||||
void SendAppearanceEffect(uint32 parm1, uint32 parm2, uint32 parm3, uint32 parm4, uint32 parm5);
|
||||
void SendAppearanceEffect(uint32 parm1, uint32 parm2, uint32 parm3, uint32 parm4, uint32 parm5, Lua_Client specific_target);
|
||||
void SetFlyMode(int in);
|
||||
void SetTexture(int in);
|
||||
void SetRace(int in);
|
||||
void SetGender(int in);
|
||||
void SetTexture(uint8 texture);
|
||||
void SetRace(uint16 race_id);
|
||||
void SetGender(uint8 gender_id);
|
||||
void SendIllusionPacket(luabind::adl::object illusion);
|
||||
void ChangeRace(int in);
|
||||
void ChangeGender(int in);
|
||||
|
||||
+43
-51
@@ -231,7 +231,7 @@ void handle_npc_hate(
|
||||
l_mob_o.push(L);
|
||||
lua_setfield(L, -2, "other");
|
||||
|
||||
lua_pushboolean(L, Strings::ToInt(data) == 0 ? false : true);
|
||||
lua_pushboolean(L, Strings::ToBool(data));
|
||||
lua_setfield(L, -2, "joined");
|
||||
}
|
||||
|
||||
@@ -301,8 +301,8 @@ void handle_npc_death(
|
||||
lua_pushinteger(L, Strings::ToInt(sep.arg[1]));
|
||||
lua_setfield(L, -2, "damage");
|
||||
|
||||
int spell_id = Strings::ToInt(sep.arg[2]);
|
||||
if(IsValidSpell(spell_id)) {
|
||||
const uint32 spell_id = Strings::ToUnsignedInt(sep.arg[2]);
|
||||
if (IsValidSpell(spell_id)) {
|
||||
Lua_Spell l_spell(&spells[spell_id]);
|
||||
luabind::adl::object l_spell_o = luabind::adl::object(L, l_spell);
|
||||
l_spell_o.push(L);
|
||||
@@ -317,16 +317,14 @@ void handle_npc_death(
|
||||
lua_pushinteger(L, Strings::ToInt(sep.arg[3]));
|
||||
lua_setfield(L, -2, "skill_id");
|
||||
|
||||
if (extra_pointers && extra_pointers->size() >= 1)
|
||||
{
|
||||
if (extra_pointers && extra_pointers->size() >= 1) {
|
||||
Lua_Corpse l_corpse(std::any_cast<Corpse*>(extra_pointers->at(0)));
|
||||
luabind::adl::object l_corpse_o = luabind::adl::object(L, l_corpse);
|
||||
l_corpse_o.push(L);
|
||||
lua_setfield(L, -2, "corpse");
|
||||
}
|
||||
|
||||
if (extra_pointers && extra_pointers->size() >= 2)
|
||||
{
|
||||
if (extra_pointers && extra_pointers->size() >= 2) {
|
||||
Lua_NPC l_npc(std::any_cast<NPC*>(extra_pointers->at(1)));
|
||||
luabind::adl::object l_npc_o = luabind::adl::object(L, l_npc);
|
||||
l_npc_o.push(L);
|
||||
@@ -343,18 +341,19 @@ void handle_npc_cast(
|
||||
uint32 extra_data,
|
||||
std::vector<std::any> *extra_pointers
|
||||
) {
|
||||
int spell_id = Strings::ToInt(data);
|
||||
if(IsValidSpell(spell_id)) {
|
||||
Lua_Spell l_spell(&spells[spell_id]);
|
||||
luabind::adl::object l_spell_o = luabind::adl::object(L, l_spell);
|
||||
l_spell_o.push(L);
|
||||
lua_setfield(L, -2, "spell");
|
||||
} else {
|
||||
Lua_Spell l_spell(nullptr);
|
||||
luabind::adl::object l_spell_o = luabind::adl::object(L, l_spell);
|
||||
l_spell_o.push(L);
|
||||
lua_setfield(L, -2, "spell");
|
||||
}
|
||||
Seperator sep(data.c_str());
|
||||
|
||||
const uint32 spell_id = Strings::ToUnsignedInt(sep.arg[0]);
|
||||
Lua_Spell l_spell(IsValidSpell(spell_id) ? &spells[spell_id] : nullptr);
|
||||
luabind::adl::object l_spell_o = luabind::adl::object(L, l_spell);
|
||||
l_spell_o.push(L);
|
||||
lua_setfield(L, -2, "spell");
|
||||
|
||||
lua_pushinteger(L, Strings::ToUnsignedInt(sep.arg[1]));
|
||||
lua_setfield(L, -2, "caster_id");
|
||||
|
||||
lua_pushinteger(L, Strings::ToUnsignedInt(sep.arg[2]));
|
||||
lua_setfield(L, -2, "caster_level");
|
||||
}
|
||||
|
||||
void handle_npc_area(
|
||||
@@ -462,16 +461,16 @@ void handle_npc_damage(
|
||||
lua_pushnumber(L, Strings::ToInt(sep.arg[3]));
|
||||
lua_setfield(L, -2, "skill_id");
|
||||
|
||||
lua_pushboolean(L, Strings::ToInt(sep.arg[4]) == 0 ? false : true);
|
||||
lua_pushboolean(L, Strings::ToBool(sep.arg[4]));
|
||||
lua_setfield(L, -2, "is_damage_shield");
|
||||
|
||||
lua_pushboolean(L, Strings::ToInt(sep.arg[5]) == 0 ? false : true);
|
||||
lua_pushboolean(L, Strings::ToBool(sep.arg[5]));
|
||||
lua_setfield(L, -2, "is_avoidable");
|
||||
|
||||
lua_pushnumber(L, Strings::ToInt(sep.arg[6]));
|
||||
lua_setfield(L, -2, "buff_slot");
|
||||
|
||||
lua_pushboolean(L, Strings::ToInt(sep.arg[7]) == 0 ? false : true);
|
||||
lua_pushboolean(L, Strings::ToBool(sep.arg[7]));
|
||||
lua_setfield(L, -2, "is_buff_tic");
|
||||
|
||||
lua_pushnumber(L, Strings::ToInt(sep.arg[8]));
|
||||
@@ -711,10 +710,10 @@ void handle_player_cast(
|
||||
|
||||
lua_setfield(L, -2, "spell");
|
||||
|
||||
lua_pushinteger(L, Strings::ToInt(sep.arg[1]));
|
||||
lua_pushinteger(L, Strings::ToUnsignedInt(sep.arg[1]));
|
||||
lua_setfield(L, -2, "caster_id");
|
||||
|
||||
lua_pushinteger(L, Strings::ToInt(sep.arg[2]));
|
||||
lua_pushinteger(L, Strings::ToUnsignedInt(sep.arg[2]));
|
||||
lua_setfield(L, -2, "caster_level");
|
||||
}
|
||||
|
||||
@@ -933,7 +932,7 @@ void handle_player_respawn(
|
||||
lua_pushinteger(L, Strings::ToInt(data));
|
||||
lua_setfield(L, -2, "option");
|
||||
|
||||
lua_pushboolean(L, extra_data == 1 ? true : false);
|
||||
lua_pushboolean(L, Strings::ToBool(std::to_string(extra_data)));
|
||||
lua_setfield(L, -2, "resurrect");
|
||||
}
|
||||
|
||||
@@ -950,7 +949,7 @@ void handle_player_packet(
|
||||
l_packet_o.push(L);
|
||||
lua_setfield(L, -2, "packet");
|
||||
|
||||
lua_pushboolean(L, extra_data == 1 ? true : false);
|
||||
lua_pushboolean(L, Strings::ToBool(std::to_string(extra_data)));
|
||||
lua_setfield(L, -2, "connecting");
|
||||
}
|
||||
|
||||
@@ -1270,16 +1269,16 @@ void handle_player_damage(
|
||||
lua_pushnumber(L, Strings::ToInt(sep.arg[3]));
|
||||
lua_setfield(L, -2, "skill_id");
|
||||
|
||||
lua_pushboolean(L, Strings::ToInt(sep.arg[4]) == 0 ? false : true);
|
||||
lua_pushboolean(L, Strings::ToBool(sep.arg[4]));
|
||||
lua_setfield(L, -2, "is_damage_shield");
|
||||
|
||||
lua_pushboolean(L, Strings::ToInt(sep.arg[5]) == 0 ? false : true);
|
||||
lua_pushboolean(L, Strings::ToBool(sep.arg[5]));
|
||||
lua_setfield(L, -2, "is_avoidable");
|
||||
|
||||
lua_pushnumber(L, Strings::ToInt(sep.arg[6]));
|
||||
lua_setfield(L, -2, "buff_slot");
|
||||
|
||||
lua_pushboolean(L, Strings::ToInt(sep.arg[7]) == 0 ? false : true);
|
||||
lua_pushboolean(L, Strings::ToBool(sep.arg[7]));
|
||||
lua_setfield(L, -2, "is_buff_tic");
|
||||
|
||||
lua_pushnumber(L, Strings::ToInt(sep.arg[8]));
|
||||
@@ -1606,7 +1605,7 @@ void handle_spell_event(
|
||||
Lua_Mob l_mob(mob);
|
||||
luabind::adl::object l_mob_o = luabind::adl::object(L, l_mob);
|
||||
l_mob_o.push(L);
|
||||
} else if(client) {
|
||||
} else if (client) {
|
||||
Lua_Mob l_client(client);
|
||||
luabind::adl::object l_client_o = luabind::adl::object(L, l_client);
|
||||
l_client_o.push(L);
|
||||
@@ -1623,13 +1622,13 @@ void handle_spell_event(
|
||||
|
||||
Seperator sep(data.c_str());
|
||||
|
||||
lua_pushinteger(L, Strings::ToInt(sep.arg[0]));
|
||||
lua_pushinteger(L, Strings::ToUnsignedInt(sep.arg[0]));
|
||||
lua_setfield(L, -2, "caster_id");
|
||||
|
||||
lua_pushinteger(L, Strings::ToInt(sep.arg[1]));
|
||||
lua_setfield(L, -2, "tics_remaining");
|
||||
|
||||
lua_pushinteger(L, Strings::ToInt(sep.arg[2]));
|
||||
lua_pushinteger(L, Strings::ToUnsignedInt(sep.arg[2]));
|
||||
lua_setfield(L, -2, "caster_level");
|
||||
|
||||
lua_pushinteger(L, Strings::ToInt(sep.arg[3]));
|
||||
@@ -1655,7 +1654,7 @@ void handle_translocate_finish(
|
||||
Lua_Mob l_mob(mob);
|
||||
luabind::adl::object l_mob_o = luabind::adl::object(L, l_mob);
|
||||
l_mob_o.push(L);
|
||||
} else if(client) {
|
||||
} else if (client) {
|
||||
Lua_Mob l_client(client);
|
||||
luabind::adl::object l_client_o = luabind::adl::object(L, l_client);
|
||||
l_client_o.push(L);
|
||||
@@ -1945,23 +1944,16 @@ void handle_bot_cast(
|
||||
) {
|
||||
Seperator sep(data.c_str());
|
||||
|
||||
int spell_id = Strings::ToInt(sep.arg[0]);
|
||||
if (IsValidSpell(spell_id)) {
|
||||
Lua_Spell l_spell(&spells[spell_id]);
|
||||
luabind::adl::object l_spell_o = luabind::adl::object(L, l_spell);
|
||||
l_spell_o.push(L);
|
||||
} else {
|
||||
Lua_Spell l_spell(nullptr);
|
||||
luabind::adl::object l_spell_o = luabind::adl::object(L, l_spell);
|
||||
l_spell_o.push(L);
|
||||
}
|
||||
|
||||
const uint32 spell_id = Strings::ToUnsignedInt(sep.arg[0]);
|
||||
Lua_Spell l_spell(IsValidSpell(spell_id) ? &spells[spell_id] : nullptr);
|
||||
luabind::adl::object l_spell_o = luabind::adl::object(L, l_spell);
|
||||
l_spell_o.push(L);
|
||||
lua_setfield(L, -2, "spell");
|
||||
|
||||
lua_pushinteger(L, Strings::ToInt(sep.arg[1]));
|
||||
lua_pushinteger(L, Strings::ToUnsignedInt(sep.arg[1]));
|
||||
lua_setfield(L, -2, "caster_id");
|
||||
|
||||
lua_pushinteger(L, Strings::ToInt(sep.arg[2]));
|
||||
lua_pushinteger(L, Strings::ToUnsignedInt(sep.arg[2]));
|
||||
lua_setfield(L, -2, "caster_level");
|
||||
}
|
||||
|
||||
@@ -1979,7 +1971,7 @@ void handle_bot_combat(
|
||||
l_mob_o.push(L);
|
||||
lua_setfield(L, -2, "other");
|
||||
|
||||
lua_pushboolean(L, Strings::ToInt(data) == 0 ? false : true);
|
||||
lua_pushboolean(L, Strings::ToBool(data));
|
||||
lua_setfield(L, -2, "joined");
|
||||
}
|
||||
|
||||
@@ -2003,7 +1995,7 @@ void handle_bot_death(
|
||||
lua_pushinteger(L, Strings::ToInt(sep.arg[1]));
|
||||
lua_setfield(L, -2, "damage");
|
||||
|
||||
int spell_id = Strings::ToInt(sep.arg[2]);
|
||||
const uint32 spell_id = Strings::ToUnsignedInt(sep.arg[2]);
|
||||
if (IsValidSpell(spell_id)) {
|
||||
Lua_Spell l_spell(&spells[spell_id]);
|
||||
luabind::adl::object l_spell_o = luabind::adl::object(L, l_spell);
|
||||
@@ -2257,16 +2249,16 @@ void handle_bot_damage(
|
||||
lua_pushnumber(L, Strings::ToInt(sep.arg[3]));
|
||||
lua_setfield(L, -2, "skill_id");
|
||||
|
||||
lua_pushboolean(L, Strings::ToInt(sep.arg[4]) == 0 ? false : true);
|
||||
lua_pushboolean(L, Strings::ToBool(sep.arg[4]));
|
||||
lua_setfield(L, -2, "is_damage_shield");
|
||||
|
||||
lua_pushboolean(L, Strings::ToInt(sep.arg[5]) == 0 ? false : true);
|
||||
lua_pushboolean(L, Strings::ToBool(sep.arg[5]));
|
||||
lua_setfield(L, -2, "is_avoidable");
|
||||
|
||||
lua_pushnumber(L, Strings::ToInt(sep.arg[6]));
|
||||
lua_setfield(L, -2, "buff_slot");
|
||||
|
||||
lua_pushboolean(L, Strings::ToInt(sep.arg[7]) == 0 ? false : true);
|
||||
lua_pushboolean(L, Strings::ToBool(sep.arg[7]));
|
||||
lua_setfield(L, -2, "is_buff_tic");
|
||||
|
||||
lua_pushnumber(L, Strings::ToInt(sep.arg[8]));
|
||||
|
||||
+2
-2
@@ -4323,7 +4323,7 @@ Merc* Merc::LoadMerc(Client *c, MercTemplate* merc_template, uint32 merchant_id,
|
||||
npc_type->race = merc_template->RaceID;
|
||||
|
||||
// Use the Gender and Size of the Merchant if possible
|
||||
uint8 tmpgender = 0;
|
||||
uint8 tmpgender = MALE;
|
||||
float tmpsize = 6.0f;
|
||||
if(merchant_id > 0)
|
||||
{
|
||||
@@ -5624,7 +5624,7 @@ void Client::SetMerc(Merc* newmerc) {
|
||||
GetMercInfo().myTemplate = nullptr;
|
||||
GetMercInfo().IsSuspended = false;
|
||||
GetMercInfo().SuspendedTime = 0;
|
||||
GetMercInfo().Gender = 0;
|
||||
GetMercInfo().Gender = MALE;
|
||||
GetMercInfo().State = 0;
|
||||
memset(GetMercInfo().merc_name, 0, 64);
|
||||
Log(Logs::General, Logs::Mercenaries, "SetMerc No Merc for %s.", GetName());
|
||||
|
||||
+160
-147
@@ -2105,7 +2105,7 @@ void Mob::SendStatsWindow(Client* c, bool use_window)
|
||||
"{}: {}{}{}",
|
||||
!faction_name.empty() ? faction_name : "Unknown Faction",
|
||||
sign,
|
||||
Strings::Commify(f.second),
|
||||
f.second,
|
||||
DialogueWindow::Break(1)
|
||||
);
|
||||
}
|
||||
@@ -3475,7 +3475,7 @@ void Mob::ShowBuffs(Client* c) {
|
||||
"{}{}{}{}{}",
|
||||
DialogueWindow::TableCell(std::to_string(i)),
|
||||
DialogueWindow::TableCell(GetSpellName(spell_id)),
|
||||
DialogueWindow::TableCell(Strings::Commify(spell_id)),
|
||||
DialogueWindow::TableCell(std::to_string(spell_id)),
|
||||
DialogueWindow::TableCell(is_permanent ? "Permanent" : time),
|
||||
DialogueWindow::TableCell(std::to_string(buffs[i].hit_number))
|
||||
)
|
||||
@@ -3518,135 +3518,100 @@ void Mob::GMMove(const glm::vec4 &position) {
|
||||
}
|
||||
}
|
||||
|
||||
void Mob::SendIllusionPacket(
|
||||
uint16 in_race,
|
||||
uint8 in_gender,
|
||||
uint8 in_texture,
|
||||
uint8 in_helmtexture,
|
||||
uint8 in_haircolor,
|
||||
uint8 in_beardcolor,
|
||||
uint8 in_eyecolor1,
|
||||
uint8 in_eyecolor2,
|
||||
uint8 in_hairstyle,
|
||||
uint8 in_luclinface,
|
||||
uint8 in_beard,
|
||||
uint8 in_aa_title,
|
||||
uint32 in_drakkin_heritage,
|
||||
uint32 in_drakkin_tattoo,
|
||||
uint32 in_drakkin_details,
|
||||
float in_size,
|
||||
bool send_appearance_effects,
|
||||
Client* target
|
||||
)
|
||||
void Mob::SendIllusionPacket(const AppearanceStruct& a)
|
||||
{
|
||||
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 new_race = (
|
||||
a.race_id != RACE_DOUG_0 ?
|
||||
a.race_id :
|
||||
(use_model ? use_model : GetBaseRace())
|
||||
);
|
||||
|
||||
race = in_race;
|
||||
if (race == 0) {
|
||||
race = use_model ? use_model : GetBaseRace();
|
||||
}
|
||||
uint8 new_gender = (
|
||||
a.gender_id != UINT8_MAX ?
|
||||
a.gender_id :
|
||||
(a.race_id ? GetDefaultGender(a.race_id, a.gender_id) : GetBaseGender())
|
||||
);
|
||||
|
||||
if (in_gender != 0xFF) {
|
||||
gender = in_gender;
|
||||
}
|
||||
else {
|
||||
gender = in_race ? GetDefaultGender(race, gender) : GetBaseGender();
|
||||
}
|
||||
float new_size = a.size <= 0.0f ? GetRaceGenderDefaultHeight(race, gender) : a.size;
|
||||
|
||||
if (in_texture == 0xFF && !IsPlayerRace(race)) {
|
||||
new_texture = GetTexture();
|
||||
}
|
||||
uint8 new_texture = a.texture == UINT8_MAX && !IsPlayerRace(a.race_id) ? GetTexture() : a.texture;
|
||||
uint8 new_helmet_texture = a.helmet_texture == UINT8_MAX && !IsPlayerRace(race) ? GetHelmTexture() : a.helmet_texture;
|
||||
|
||||
if (in_helmtexture == 0xFF && !IsPlayerRace(race)) {
|
||||
new_helmtexture = GetHelmTexture();
|
||||
}
|
||||
uint8 new_hair = a.hair == UINT8_MAX ? GetHairStyle() : a.hair;
|
||||
uint8 new_hair_color = a.hair_color == UINT8_MAX ? GetHairColor() : a.hair_color;
|
||||
|
||||
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;
|
||||
uint8 new_beard = a.beard == UINT8_MAX ? GetBeard() : a.beard;
|
||||
uint8 new_beard_color = a.beard_color == UINT8_MAX ? GetBeardColor() : a.beard_color;
|
||||
|
||||
uint8 new_eye_color_one = a.eye_color_one == UINT8_MAX ? GetEyeColor1() : a.eye_color_one;
|
||||
uint8 new_eye_color_two = a.eye_color_two == UINT8_MAX ? GetEyeColor2() : a.eye_color_two;
|
||||
|
||||
uint8 new_face = a.face == UINT8_MAX ? GetLuclinFace() : a.face;
|
||||
|
||||
uint32 new_drakkin_details = a.drakkin_details == UINT32_MAX ? GetDrakkinDetails() : a.drakkin_details;
|
||||
uint32 new_drakkin_heritage = a.drakkin_heritage == UINT32_MAX ? GetDrakkinHeritage() : a.drakkin_heritage;
|
||||
uint32 new_drakkin_tattoo = a.drakkin_tattoo == UINT32_MAX ? GetDrakkinTattoo() : a.drakkin_tattoo;
|
||||
|
||||
// Reset features to Base from the Player Profile
|
||||
if (IsClient() && in_race == 0) {
|
||||
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();
|
||||
if (IsClient() && a.race_id == RACE_DOUG_0) {
|
||||
new_beard = CastToClient()->GetBaseBeard();
|
||||
new_beard_color = CastToClient()->GetBaseBeardColor();
|
||||
new_drakkin_details = CastToClient()->GetBaseDetails();
|
||||
new_drakkin_heritage = CastToClient()->GetBaseHeritage();
|
||||
new_drakkin_tattoo = CastToClient()->GetBaseTattoo();
|
||||
new_eye_color_one = CastToClient()->GetBaseEyeColor();
|
||||
new_eye_color_two = CastToClient()->GetBaseEyeColor();
|
||||
new_face = CastToClient()->GetBaseFace();
|
||||
new_gender = CastToClient()->GetBaseGender();
|
||||
new_helmet_texture = UINT8_MAX;
|
||||
new_hair = CastToClient()->GetBaseHairStyle();
|
||||
new_hair_color = CastToClient()->GetBaseHairColor();
|
||||
new_race = CastToClient()->GetBaseRace();
|
||||
new_size = CastToClient()->GetSize();
|
||||
new_texture = UINT8_MAX;
|
||||
}
|
||||
|
||||
// update internal values for mob
|
||||
size = (in_size <= 0.0f) ? GetRaceGenderDefaultHeight(race, gender) : in_size;
|
||||
if (new_texture != 0xFF) {
|
||||
texture = new_texture;
|
||||
}
|
||||
if (new_helmtexture != 0xFF) {
|
||||
helmtexture = new_helmtexture;
|
||||
}
|
||||
haircolor = new_haircolor;
|
||||
beardcolor = new_beardcolor;
|
||||
eyecolor1 = new_eyecolor1;
|
||||
eyecolor2 = new_eyecolor2;
|
||||
hairstyle = new_hairstyle;
|
||||
luclinface = new_luclinface;
|
||||
beard = new_beard;
|
||||
beardcolor = new_beard_color;
|
||||
drakkin_heritage = new_drakkin_heritage;
|
||||
drakkin_tattoo = new_drakkin_tattoo;
|
||||
drakkin_details = new_drakkin_details;
|
||||
eyecolor1 = new_eye_color_one;
|
||||
eyecolor2 = new_eye_color_two;
|
||||
luclinface = new_face;
|
||||
gender = new_gender;
|
||||
hairstyle = new_hair;
|
||||
haircolor = new_hair_color;
|
||||
helmtexture = new_helmet_texture;
|
||||
race = new_race;
|
||||
size = new_size;
|
||||
texture = new_texture;
|
||||
|
||||
auto outapp = new EQApplicationPacket(OP_Illusion, sizeof(Illusion_Struct));
|
||||
auto is = (Illusion_Struct *) outapp->pBuffer;
|
||||
|
||||
auto outapp = new EQApplicationPacket(OP_Illusion, sizeof(Illusion_Struct));
|
||||
Illusion_Struct *is = (Illusion_Struct *) outapp->pBuffer;
|
||||
is->spawnid = GetID();
|
||||
strcpy(is->charname, GetCleanName());
|
||||
is->race = race;
|
||||
is->gender = gender;
|
||||
is->texture = new_texture;
|
||||
is->helmtexture = new_helmtexture;
|
||||
is->haircolor = new_haircolor;
|
||||
is->beardcolor = new_beardcolor;
|
||||
strn0cpy(is->charname, GetCleanName(), sizeof(is->charname));
|
||||
is->beardcolor = new_beard_color;
|
||||
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;
|
||||
is->eyecolor1 = new_eye_color_one;
|
||||
is->eyecolor2 = new_eye_color_two;
|
||||
is->face = new_face;
|
||||
is->gender = new_gender;
|
||||
is->hairstyle = new_hair;
|
||||
is->haircolor = new_hair_color;
|
||||
is->helmtexture = new_helmet_texture;
|
||||
is->race = new_race;
|
||||
is->size = new_size;
|
||||
is->texture = new_texture;
|
||||
|
||||
if (!target) {
|
||||
if (!a.target) {
|
||||
entity_list.QueueClients(this, outapp);
|
||||
} else {
|
||||
target->QueuePacket(outapp, false);
|
||||
a.target->QueuePacket(outapp, false);
|
||||
}
|
||||
|
||||
safe_delete(outapp);
|
||||
@@ -3654,7 +3619,7 @@ void Mob::SendIllusionPacket(
|
||||
/* Refresh armor and tints after send illusion packet */
|
||||
SendArmorAppearance();
|
||||
|
||||
if (send_appearance_effects) {
|
||||
if (a.send_effects) {
|
||||
SendSavedAppearenceEffects(nullptr);
|
||||
}
|
||||
|
||||
@@ -3663,17 +3628,17 @@ void Mob::SendIllusionPacket(
|
||||
race,
|
||||
gender,
|
||||
new_texture,
|
||||
new_helmtexture,
|
||||
new_haircolor,
|
||||
new_beardcolor,
|
||||
new_eyecolor1,
|
||||
new_eyecolor2,
|
||||
new_hairstyle,
|
||||
new_luclinface,
|
||||
new_helmet_texture,
|
||||
new_hair_color,
|
||||
new_beard_color,
|
||||
new_eye_color_one,
|
||||
new_eye_color_two,
|
||||
new_hair,
|
||||
new_face,
|
||||
new_drakkin_heritage,
|
||||
new_drakkin_tattoo,
|
||||
new_drakkin_details,
|
||||
size,
|
||||
new_size,
|
||||
target ? target->GetCleanName() : "No Target"
|
||||
);
|
||||
}
|
||||
@@ -3903,21 +3868,22 @@ bool Mob::RandomizeFeatures(bool send_illusion, bool set_variables)
|
||||
|
||||
if (send_illusion) {
|
||||
SendIllusionPacket(
|
||||
GetRace(),
|
||||
current_gender,
|
||||
new_texture,
|
||||
new_helm_texture,
|
||||
new_hair_color,
|
||||
new_beard_color,
|
||||
new_eye_color_one,
|
||||
new_eye_color_two,
|
||||
new_hair_style,
|
||||
new_luclin_face,
|
||||
new_beard,
|
||||
0xFF,
|
||||
new_drakkin_heritage,
|
||||
new_drakkin_tattoo,
|
||||
new_drakkin_details
|
||||
AppearanceStruct{
|
||||
.beard = new_beard,
|
||||
.beard_color = new_beard_color,
|
||||
.drakkin_details = new_drakkin_details,
|
||||
.drakkin_heritage = new_drakkin_heritage,
|
||||
.drakkin_tattoo = new_drakkin_tattoo,
|
||||
.eye_color_one = new_eye_color_one,
|
||||
.eye_color_two = new_eye_color_two,
|
||||
.face = new_luclin_face,
|
||||
.gender_id = current_gender,
|
||||
.hair = new_hair_style,
|
||||
.hair_color = new_hair_color,
|
||||
.helmet_texture = new_helm_texture,
|
||||
.race_id = GetRace(),
|
||||
.texture = new_texture,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -8153,21 +8119,23 @@ void Mob::CloneAppearance(Mob* other, bool clone_name)
|
||||
}
|
||||
|
||||
SendIllusionPacket(
|
||||
other->GetRace(),
|
||||
other->GetGender(),
|
||||
other->GetTexture(),
|
||||
other->GetHelmTexture(),
|
||||
other->GetHairColor(),
|
||||
other->GetBeardColor(),
|
||||
other->GetEyeColor1(),
|
||||
other->GetEyeColor2(),
|
||||
other->GetHairStyle(),
|
||||
other->GetBeard(),
|
||||
0xFF,
|
||||
other->GetRace() == DRAKKIN ? other->GetDrakkinHeritage() : 0xFFFFFFFF,
|
||||
other->GetRace() == DRAKKIN ? other->GetDrakkinTattoo() : 0xFFFFFFFF,
|
||||
other->GetRace() == DRAKKIN ? other->GetDrakkinDetails() : 0xFFFFFFFF,
|
||||
other->GetSize()
|
||||
AppearanceStruct{
|
||||
.beard = other->GetBeard(),
|
||||
.beard_color = other->GetBeardColor(),
|
||||
.drakkin_details = other->GetDrakkinDetails(),
|
||||
.drakkin_heritage = other->GetDrakkinHeritage(),
|
||||
.drakkin_tattoo = other->GetDrakkinTattoo(),
|
||||
.eye_color_one = other->GetEyeColor1(),
|
||||
.eye_color_two = other->GetEyeColor2(),
|
||||
.face = other->GetLuclinFace(),
|
||||
.gender_id = other->GetGender(),
|
||||
.hair = other->GetHairStyle(),
|
||||
.hair_color = other->GetHairColor(),
|
||||
.helmet_texture = other->GetHelmTexture(),
|
||||
.race_id = other->GetRace(),
|
||||
.size = other->GetSize(),
|
||||
.texture = other->GetTexture(),
|
||||
}
|
||||
);
|
||||
|
||||
for (
|
||||
@@ -8365,3 +8333,48 @@ uint32 Mob::GetMobTypeIdentifier()
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Mob::HandleDoorOpen()
|
||||
{
|
||||
for (auto e : entity_list.GetDoorsList()) {
|
||||
Doors *d = e.second;
|
||||
if (d->GetKeyItem()) {
|
||||
continue;
|
||||
}
|
||||
if (d->GetLockpick()) {
|
||||
continue;
|
||||
}
|
||||
if (d->IsDoorOpen()) {
|
||||
continue;
|
||||
}
|
||||
if (d->IsDoorBlacklisted()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the door is a trigger door, check if the trigger door is open
|
||||
if (d->GetTriggerDoorID() > 0) {
|
||||
auto td = entity_list.GetDoorsByDoorID(d->GetTriggerDoorID());
|
||||
if (td) {
|
||||
if (Strings::RemoveNumbers(d->GetDoorName()) != Strings::RemoveNumbers(td->GetDoorName())) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (d->GetDoorParam() > 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
float distance = DistanceSquared(m_Position, d->GetPosition());
|
||||
float distance_scan_door_open = 20;
|
||||
|
||||
if (distance <= (distance_scan_door_open * distance_scan_door_open)) {
|
||||
// Make sure we're opening a door within height relevance and not platforms above or below us
|
||||
if (std::abs(m_Position.z - d->GetPosition().z) > 10) {
|
||||
continue;
|
||||
}
|
||||
|
||||
d->ForceOpen(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+26
-22
@@ -69,6 +69,27 @@ enum class eSpecialAttacks : int {
|
||||
ChaoticStab
|
||||
};
|
||||
|
||||
struct AppearanceStruct {
|
||||
uint8 aa_title = UINT8_MAX;
|
||||
uint8 beard = UINT8_MAX;
|
||||
uint8 beard_color = UINT8_MAX;
|
||||
uint32 drakkin_details = UINT32_MAX;
|
||||
uint32 drakkin_heritage = UINT32_MAX;
|
||||
uint32 drakkin_tattoo = UINT32_MAX;
|
||||
uint8 eye_color_one = UINT8_MAX;
|
||||
uint8 eye_color_two = UINT8_MAX;
|
||||
uint8 face = UINT8_MAX;
|
||||
uint8 gender_id = UINT8_MAX;
|
||||
uint8 hair = UINT8_MAX;
|
||||
uint8 hair_color = UINT8_MAX;
|
||||
uint8 helmet_texture = UINT8_MAX;
|
||||
uint16 race_id = RACE_DOUG_0;
|
||||
bool send_effects = true;
|
||||
float size = -1.0f;
|
||||
Client *target = nullptr;
|
||||
uint8 texture = UINT8_MAX;
|
||||
};
|
||||
|
||||
class DataBucketKey;
|
||||
class Mob : public Entity {
|
||||
public:
|
||||
@@ -228,7 +249,7 @@ public:
|
||||
inline int GetMitigationAC() { return mitigation_ac; }
|
||||
void MeleeMitigation(Mob *attacker, DamageHitInfo &hit, ExtraAttackOptions *opts = nullptr);
|
||||
double RollD20(int offense, int mitigation); // CALL THIS FROM THE DEFENDER
|
||||
bool CombatRange(Mob* other, float fixed_size_mod = 1.0, bool aeRampage = false);
|
||||
bool CombatRange(Mob* other, float fixed_size_mod = 1.0, bool aeRampage = false, ExtraAttackOptions *opts = nullptr);
|
||||
virtual inline bool IsBerserk() { return false; } // only clients
|
||||
void RogueEvade(Mob *other);
|
||||
void CommonOutgoingHitSuccess(Mob *defender, DamageHitInfo &hit, ExtraAttackOptions *opts = nullptr);
|
||||
@@ -436,7 +457,7 @@ public:
|
||||
virtual uint32 GetLastBuffSlot(bool disc, bool song);
|
||||
virtual void InitializeBuffSlots() { buffs = nullptr; }
|
||||
virtual void UninitializeBuffSlots() { }
|
||||
EQApplicationPacket *MakeBuffsPacket(bool for_target = true);
|
||||
EQApplicationPacket *MakeBuffsPacket(bool for_target = true, bool clear_buffs = false);
|
||||
void SendBuffsToClient(Client *c);
|
||||
inline Buffs_Struct* GetBuffs() { return buffs; }
|
||||
void DoGravityEffect();
|
||||
@@ -889,26 +910,7 @@ public:
|
||||
|
||||
int64 CalcFocusEffect(focusType type, uint16 focus_id, uint16 spell_id, bool best_focus=false, uint16 casterid = 0, Mob *caster = nullptr);
|
||||
uint8 IsFocusEffect(uint16 spellid, int effect_index, bool AA=false,uint32 aa_effect=0);
|
||||
void SendIllusionPacket(
|
||||
uint16 in_race,
|
||||
uint8 in_gender = 0xFF,
|
||||
uint8 in_texture = 0xFF,
|
||||
uint8 in_helmtexture = 0xFF,
|
||||
uint8 in_haircolor = 0xFF,
|
||||
uint8 in_beardcolor = 0xFF,
|
||||
uint8 in_eyecolor1 = 0xFF,
|
||||
uint8 in_eyecolor2 = 0xFF,
|
||||
uint8 in_hairstyle = 0xFF,
|
||||
uint8 in_luclinface = 0xFF,
|
||||
uint8 in_beard = 0xFF,
|
||||
uint8 in_aa_title = 0xFF,
|
||||
uint32 in_drakkin_heritage = 0xFFFFFFFF,
|
||||
uint32 in_drakkin_tattoo = 0xFFFFFFFF,
|
||||
uint32 in_drakkin_details = 0xFFFFFFFF,
|
||||
float in_size = -1.0f,
|
||||
bool send_appearance_effects = true,
|
||||
Client* target = nullptr
|
||||
);
|
||||
void SendIllusionPacket(const AppearanceStruct& a);
|
||||
void CloneAppearance(Mob* other, bool clone_name = false);
|
||||
void SetFaceAppearance(const FaceChange_Struct& face, bool skip_sender = false);
|
||||
bool RandomizeFeatures(bool send_illusion = true, bool set_variables = true);
|
||||
@@ -1400,6 +1402,7 @@ public:
|
||||
int64 GetHPRegen() const;
|
||||
int64 GetHPRegenPerSecond() const;
|
||||
int64 GetManaRegen() const;
|
||||
int64 GetEnduranceRegen() const;
|
||||
|
||||
bool CanOpenDoors() const;
|
||||
void SetCanOpenDoors(bool can_open);
|
||||
@@ -1866,6 +1869,7 @@ private:
|
||||
void SetHeroicWisBonuses(StatBonuses* n);
|
||||
|
||||
void DoSpellInterrupt(uint16 spell_id, int32 mana_cost, int my_curmana);
|
||||
void HandleDoorOpen();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
+6
-46
@@ -981,52 +981,7 @@ void Mob::AI_Process() {
|
||||
|
||||
if (moving && CanOpenDoors()) {
|
||||
if (AI_scan_door_open_timer->Check()) {
|
||||
auto &door_list = entity_list.GetDoorsList();
|
||||
for (auto itr : door_list) {
|
||||
Doors *door = itr.second;
|
||||
|
||||
if (door->GetKeyItem()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (door->GetLockpick()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (door->IsDoorOpen()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (door->GetTriggerDoorID() > 0) {
|
||||
auto trigger_door = entity_list.GetDoorsByDoorID(door->GetTriggerDoorID());
|
||||
if (trigger_door) {
|
||||
if (Strings::RemoveNumbers(door->GetDoorName()) !=
|
||||
Strings::RemoveNumbers(trigger_door->GetDoorName())) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (door->GetDoorParam() > 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
float distance = DistanceSquared(m_Position, door->GetPosition());
|
||||
float distance_scan_door_open = 20;
|
||||
|
||||
if (distance <= (distance_scan_door_open * distance_scan_door_open)) {
|
||||
|
||||
/**
|
||||
* Make sure we're opening a door within height relevance and not platforms
|
||||
* above or below
|
||||
*/
|
||||
if (std::abs(m_Position.z - door->GetPosition().z) > 10) {
|
||||
continue;
|
||||
}
|
||||
|
||||
door->ForceOpen(this);
|
||||
}
|
||||
}
|
||||
HandleDoorOpen();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1330,6 +1285,11 @@ void Mob::AI_Process() {
|
||||
opts.crit_flat = cur;
|
||||
}
|
||||
|
||||
cur = GetSpecialAbilityParam(SPECATK_AREA_RAMPAGE, 8);
|
||||
if (cur > 0) {
|
||||
opts.range_percent = cur;
|
||||
}
|
||||
|
||||
AreaRampage(&opts);
|
||||
specialed = true;
|
||||
}
|
||||
|
||||
+6
-19
@@ -199,6 +199,7 @@ NPC::NPC(const NPCType *npc_type_data, Spawn2 *in_respawn, const glm::vec4 &posi
|
||||
CHA = npc_type_data->CHA;
|
||||
npc_mana = npc_type_data->Mana;
|
||||
m_is_underwater_only = npc_type_data->underwater;
|
||||
m_is_quest_npc = npc_type_data->is_quest_npc;
|
||||
|
||||
//quick fix of ordering if they screwed it up in the DB
|
||||
if (max_dmg < min_dmg) {
|
||||
@@ -1219,7 +1220,7 @@ void NPC::SpawnGridNodeNPC(const glm::vec4 &position, int32 grid_id, int32 grid_
|
||||
npc_type->current_hp = 4000000;
|
||||
npc_type->max_hp = 4000000;
|
||||
npc_type->race = 2254;
|
||||
npc_type->gender = 2;
|
||||
npc_type->gender = NEUTER;
|
||||
npc_type->class_ = 9;
|
||||
npc_type->deity = 1;
|
||||
npc_type->level = 200;
|
||||
@@ -2583,30 +2584,16 @@ void NPC::ModifyNPCStat(const std::string& stat, const std::string& value)
|
||||
}
|
||||
else if (stat_lower == "min_hit") {
|
||||
min_dmg = Strings::ToInt(value);
|
||||
|
||||
// TODO: fix DB
|
||||
|
||||
if (min_dmg > max_dmg) {
|
||||
const auto temporary_damage = max_dmg;
|
||||
max_dmg = min_dmg;
|
||||
min_dmg = temporary_damage;
|
||||
}
|
||||
|
||||
// Clamp max_dmg to be >= min_dmg
|
||||
max_dmg = std::max(min_dmg, max_dmg);
|
||||
base_damage = round((max_dmg - min_dmg) / 1.9);
|
||||
min_damage = min_dmg - round(base_damage / 10.0);
|
||||
return;
|
||||
}
|
||||
else if (stat_lower == "max_hit") {
|
||||
max_dmg = Strings::ToInt(value);
|
||||
|
||||
// TODO: fix DB
|
||||
|
||||
if (max_dmg < min_dmg) {
|
||||
const auto temporary_damage = min_dmg;
|
||||
min_dmg = max_dmg;
|
||||
max_dmg = temporary_damage;
|
||||
}
|
||||
|
||||
// Clamp min_dmg to be <= max_dmg
|
||||
min_dmg = std::min(min_dmg, max_dmg);
|
||||
base_damage = round((max_dmg - min_dmg) / 1.9);
|
||||
min_damage = min_dmg - round(base_damage / 10.0);
|
||||
return;
|
||||
|
||||
@@ -443,6 +443,7 @@ public:
|
||||
const bool HasPrivateCorpse() const { return NPCTypedata_ours ? NPCTypedata_ours->private_corpse : NPCTypedata->private_corpse; }
|
||||
|
||||
virtual const bool IsUnderwaterOnly() const { return m_is_underwater_only; }
|
||||
virtual const bool IsQuestNPC() const { return m_is_quest_npc; }
|
||||
const char* GetRawNPCTypeName() const { return NPCTypedata_ours ? NPCTypedata_ours->name : NPCTypedata->name; }
|
||||
|
||||
virtual int GetKillExpMod() const { return NPCTypedata_ours ? NPCTypedata_ours->exp_mod : NPCTypedata->exp_mod; }
|
||||
@@ -670,6 +671,7 @@ protected:
|
||||
uint32 adventure_template_id;
|
||||
|
||||
bool m_is_underwater_only = false;
|
||||
bool m_is_quest_npc = false;
|
||||
|
||||
//mercenary stuff
|
||||
std::list<MercType> mercTypeList;
|
||||
|
||||
@@ -135,31 +135,24 @@ void NpcScaleManager::ScaleNPC(
|
||||
npc->ModifyNPCStat("phr", std::to_string(scale_data.physical_resist));
|
||||
}
|
||||
|
||||
auto min_damage_set = false;
|
||||
// If either is scaled, both need to be. The values for base_damage and min_damage will be in flux until
|
||||
// both are complete.
|
||||
|
||||
if (always_scale || npc->GetMinDMG() == 0) {
|
||||
if (always_scale || npc->GetMinDMG() == 0 || npc->GetMaxDMG() == 0) {
|
||||
int64 min_dmg = scale_data.min_dmg;
|
||||
int64 max_dmg = scale_data.max_dmg;
|
||||
|
||||
if (RuleB(Combat, UseNPCDamageClassLevelMods)) {
|
||||
uint32 class_level_damage_mod = GetClassLevelDamageMod(npc->GetLevel(), npc->GetClass());
|
||||
min_dmg = (min_dmg * class_level_damage_mod) / 220;
|
||||
|
||||
LogNPCScaling("ClassLevelDamageMod::min_dmg base: [{}] calc: [{}]", scale_data.min_dmg, min_dmg);
|
||||
max_dmg = (max_dmg * class_level_damage_mod) / 220;
|
||||
}
|
||||
|
||||
npc->ModifyNPCStat("min_hit", std::to_string(min_dmg));
|
||||
min_damage_set = true;
|
||||
}
|
||||
|
||||
if (always_scale || npc->GetMaxDMG() == 0 || min_damage_set) {
|
||||
int64 max_dmg = scale_data.max_dmg;
|
||||
if (RuleB(Combat, UseNPCDamageClassLevelMods)) {
|
||||
uint32 class_level_damage_mod = GetClassLevelDamageMod(npc->GetLevel(), npc->GetClass());
|
||||
max_dmg = (scale_data.max_dmg * class_level_damage_mod) / 220;
|
||||
|
||||
LogNPCScaling("ClassLevelDamageMod::max_dmg base: [{}] calc: [{}]", scale_data.max_dmg, max_dmg);
|
||||
}
|
||||
|
||||
npc->ModifyNPCStat("max_hit", std::to_string(max_dmg));
|
||||
|
||||
LogNPCScaling("ClassLevelDamageMod::min_dmg base: [{}] calc: [{}]", scale_data.min_dmg, min_dmg);
|
||||
LogNPCScaling("ClassLevelDamageMod::max_dmg base: [{}] calc: [{}]", scale_data.max_dmg, max_dmg);
|
||||
}
|
||||
|
||||
if (always_scale || (npc->GetHPRegen() == 0 && is_auto_scaled)) {
|
||||
|
||||
@@ -529,7 +529,7 @@ void PathfinderWaypoint::ShowNode(const Node &n) {
|
||||
npc_type->current_hp = 4000000;
|
||||
npc_type->max_hp = 4000000;
|
||||
npc_type->race = 2254;
|
||||
npc_type->gender = 2;
|
||||
npc_type->gender = NEUTER;
|
||||
npc_type->class_ = 9;
|
||||
npc_type->deity = 1;
|
||||
npc_type->level = 75;
|
||||
|
||||
+2
-15
@@ -614,11 +614,8 @@ Bot* Perl_EntityList_GetRandomBot(EntityList* self, float x, float y, float z, f
|
||||
perl::array Perl_EntityList_GetCloseMobList(EntityList* self, Mob* mob)
|
||||
{
|
||||
perl::array result;
|
||||
|
||||
const auto& l = self->GetCloseMobList(mob);
|
||||
|
||||
result.reserve(l.size());
|
||||
|
||||
for (const auto& e : l) {
|
||||
result.push_back(e.second);
|
||||
}
|
||||
@@ -629,12 +626,7 @@ perl::array Perl_EntityList_GetCloseMobList(EntityList* self, Mob* mob)
|
||||
perl::array Perl_EntityList_GetCloseMobList(EntityList* self, Mob* mob, float distance)
|
||||
{
|
||||
perl::array result;
|
||||
|
||||
const auto& l = self->GetCloseMobList(mob, distance);
|
||||
|
||||
result.reserve(l.size());
|
||||
|
||||
for (const auto& e : l) {
|
||||
for (const auto& e : self->GetCloseMobList(mob, distance)) {
|
||||
if (mob->CalculateDistance(e.second) <= distance) {
|
||||
result.push_back(e.second);
|
||||
}
|
||||
@@ -646,12 +638,7 @@ perl::array Perl_EntityList_GetCloseMobList(EntityList* self, Mob* mob, float di
|
||||
perl::array Perl_EntityList_GetCloseMobList(EntityList* self, Mob* mob, float distance, bool ignore_self)
|
||||
{
|
||||
perl::array result;
|
||||
|
||||
const auto& l = self->GetCloseMobList(mob, distance);
|
||||
|
||||
result.reserve(l.size());
|
||||
|
||||
for (const auto& e : l) {
|
||||
for (const auto& e : self->GetCloseMobList(mob, distance)) {
|
||||
if (ignore_self && e.second == mob) {
|
||||
continue;
|
||||
}
|
||||
|
||||
+372
-74
@@ -1809,10 +1809,26 @@ void Perl_Mob_SendAppearanceEffectGround(Mob* self, int32 parm1, int32 parm2, in
|
||||
|
||||
void Perl_Mob_RemoveAllAppearanceEffects(Mob* self) // @categories Script Utility
|
||||
{
|
||||
self->SendIllusionPacket(self->GetRace(), self->GetGender(), self->GetTexture(), self->GetHelmTexture(),
|
||||
self->GetHairColor(), self->GetBeardColor(), self->GetEyeColor1(), self->GetEyeColor2(),
|
||||
self->GetHairStyle(), self->GetLuclinFace(), self->GetBeard(), 0xFF,
|
||||
self->GetDrakkinHeritage(), self->GetDrakkinTattoo(), self->GetDrakkinDetails(), self->GetSize(), false);
|
||||
self->SendIllusionPacket(
|
||||
AppearanceStruct{
|
||||
.beard = self->GetBeard(),
|
||||
.beard_color = self->GetBeardColor(),
|
||||
.drakkin_details = self->GetDrakkinDetails(),
|
||||
.drakkin_heritage = self->GetDrakkinHeritage(),
|
||||
.drakkin_tattoo = self->GetDrakkinTattoo(),
|
||||
.eye_color_one = self->GetEyeColor1(),
|
||||
.eye_color_two = self->GetEyeColor2(),
|
||||
.face = self->GetLuclinFace(),
|
||||
.gender_id = self->GetGender(),
|
||||
.hair = self->GetHairStyle(),
|
||||
.hair_color = self->GetHairColor(),
|
||||
.helmet_texture = self->GetHelmTexture(),
|
||||
.race_id = self->GetRace(),
|
||||
.send_effects = false,
|
||||
.size = self->GetSize(),
|
||||
.texture = self->GetTexture(),
|
||||
}
|
||||
);
|
||||
self->ClearAppearenceEffects();
|
||||
}
|
||||
|
||||
@@ -1821,134 +1837,416 @@ void Perl_Mob_SetFlyMode(Mob* self, int flymode) // @categories Script Utility
|
||||
self->SetFlyMode(static_cast<GravityBehavior>(flymode));
|
||||
}
|
||||
|
||||
void Perl_Mob_SetTexture(Mob* self, int32 texture) // @categories Stats and Attributes
|
||||
void Perl_Mob_SetTexture(Mob* self, uint8 texture) // @categories Stats and Attributes
|
||||
{
|
||||
self->SendIllusionPacket(self->GetRace(), 0xFF, texture);
|
||||
self->SendIllusionPacket(
|
||||
AppearanceStruct{
|
||||
.race_id = self->GetRace(),
|
||||
.texture = texture,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void Perl_Mob_SetRace(Mob* self, int32 race) // @categories Stats and Attributes
|
||||
void Perl_Mob_SetRace(Mob* self, uint16 race_id) // @categories Stats and Attributes
|
||||
{
|
||||
self->SendIllusionPacket(race);
|
||||
self->SendIllusionPacket(
|
||||
AppearanceStruct{
|
||||
.race_id = race_id,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void Perl_Mob_SetGender(Mob* self, int32 gender) // @categories Stats and Attributes
|
||||
void Perl_Mob_SetGender(Mob* self, uint8 gender_id) // @categories Stats and Attributes
|
||||
{
|
||||
self->SendIllusionPacket(self->GetRace(), gender);
|
||||
self->SendIllusionPacket(
|
||||
AppearanceStruct{
|
||||
.gender_id = gender_id,
|
||||
.race_id = self->GetRace(),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// todo: SendIllusion should be sent in a hash like lua
|
||||
void Perl_Mob_SendIllusion(Mob* self, uint16 race) // @categories Script Utility
|
||||
void Perl_Mob_SendIllusion(Mob *self, uint16 race_id) // @categories Script Utility
|
||||
{
|
||||
self->SendIllusionPacket(race);
|
||||
self->SendIllusionPacket(
|
||||
AppearanceStruct{
|
||||
.race_id = race_id,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void Perl_Mob_SendIllusion(Mob* self, uint16 race, uint8 gender) // @categories Script Utility
|
||||
void Perl_Mob_SendIllusion(Mob *self, uint16 race_id, uint8 gender_id) // @categories Script Utility
|
||||
{
|
||||
self->SendIllusionPacket(race, gender);
|
||||
self->SendIllusionPacket(
|
||||
AppearanceStruct{
|
||||
.gender_id = gender_id,
|
||||
.race_id = race_id,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void Perl_Mob_SendIllusion(Mob* self, uint16 race, uint8 gender, uint8 texture) // @categories Script Utility
|
||||
void Perl_Mob_SendIllusion(Mob *self, uint16 race_id, uint8 gender_id, uint8 texture) // @categories Script Utility
|
||||
{
|
||||
self->SendIllusionPacket(race, gender, texture);
|
||||
self->SendIllusionPacket(
|
||||
AppearanceStruct{
|
||||
.gender_id = gender_id,
|
||||
.race_id = race_id,
|
||||
.texture = texture,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void Perl_Mob_SendIllusion(Mob* self, uint16 race, uint8 gender, uint8 texture, uint8 helmtexture) // @categories Script Utility
|
||||
void Perl_Mob_SendIllusion(
|
||||
Mob *self,
|
||||
uint16 race_id,
|
||||
uint8 gender_id,
|
||||
uint8 texture,
|
||||
uint8 helmet_texture
|
||||
) // @categories Script Utility
|
||||
{
|
||||
self->SendIllusionPacket(race, gender, texture, helmtexture);
|
||||
self->SendIllusionPacket(
|
||||
AppearanceStruct{
|
||||
.gender_id = gender_id,
|
||||
.helmet_texture = helmet_texture,
|
||||
.race_id = race_id,
|
||||
.texture = texture,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void Perl_Mob_SendIllusion(Mob* self, uint16 race, uint8 gender, uint8 texture, uint8 helmtexture, uint8 face) // @categories Script Utility
|
||||
void Perl_Mob_SendIllusion(
|
||||
Mob *self,
|
||||
uint16 race_id,
|
||||
uint8 gender_id,
|
||||
uint8 texture,
|
||||
uint8 helmet_texture,
|
||||
uint8 face
|
||||
) // @categories Script Utility
|
||||
{
|
||||
self->SendIllusionPacket(race, gender, texture, helmtexture, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, face);
|
||||
self->SendIllusionPacket(
|
||||
AppearanceStruct{
|
||||
.face = face,
|
||||
.gender_id = gender_id,
|
||||
.helmet_texture = helmet_texture,
|
||||
.race_id = race_id,
|
||||
.texture = texture,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void Perl_Mob_SendIllusion(Mob* self, uint16 race, uint8 gender, uint8 texture, uint8 helmtexture, uint8 face, uint8 hairstyle) // @categories Script Utility
|
||||
void Perl_Mob_SendIllusion(
|
||||
Mob *self,
|
||||
uint16 race_id,
|
||||
uint8 gender_id,
|
||||
uint8 texture,
|
||||
uint8 helmet_texture,
|
||||
uint8 face,
|
||||
uint8 hair
|
||||
) // @categories Script Utility
|
||||
{
|
||||
self->SendIllusionPacket(race, gender, texture, helmtexture, 0xFF, 0xFF, 0xFF, 0xFF, hairstyle, face);
|
||||
self->SendIllusionPacket(
|
||||
AppearanceStruct{
|
||||
.face = face,
|
||||
.gender_id = gender_id,
|
||||
.hair = hair,
|
||||
.helmet_texture = helmet_texture,
|
||||
.race_id = race_id,
|
||||
.texture = texture,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void Perl_Mob_SendIllusion(Mob* self, uint16 race, uint8 gender, uint8 texture, uint8 helmtexture, uint8 face, uint8 hairstyle, uint8 haircolor) // @categories Script Utility
|
||||
void Perl_Mob_SendIllusion(
|
||||
Mob *self,
|
||||
uint16 race_id,
|
||||
uint8 gender_id,
|
||||
uint8 texture,
|
||||
uint8 helmet_texture,
|
||||
uint8 face,
|
||||
uint8 hair,
|
||||
uint8 hair_color
|
||||
) // @categories Script Utility
|
||||
{
|
||||
self->SendIllusionPacket(race, gender, texture, helmtexture, haircolor, 0xFF, 0xFF, 0xFF, hairstyle, face);
|
||||
self->SendIllusionPacket(
|
||||
AppearanceStruct{
|
||||
.face = face,
|
||||
.gender_id = gender_id,
|
||||
.hair = hair,
|
||||
.hair_color = hair_color,
|
||||
.helmet_texture = helmet_texture,
|
||||
.race_id = race_id,
|
||||
.texture = texture,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void Perl_Mob_SendIllusion(Mob* self, uint16 race, uint8 gender, uint8 texture, uint8 helmtexture, uint8 face, uint8 hairstyle, uint8 haircolor, uint8 beard) // @categories Script Utility
|
||||
void Perl_Mob_SendIllusion(
|
||||
Mob *self,
|
||||
uint16 race_id,
|
||||
uint8 gender_id,
|
||||
uint8 texture,
|
||||
uint8 helmet_texture,
|
||||
uint8 face,
|
||||
uint8 hair,
|
||||
uint8 hair_color,
|
||||
uint8 beard
|
||||
) // @categories Script Utility
|
||||
{
|
||||
self->SendIllusionPacket(race, gender, texture, helmtexture, haircolor, 0xFF, 0xFF, 0xFF, hairstyle, face, beard);
|
||||
self->SendIllusionPacket(
|
||||
AppearanceStruct{
|
||||
.beard = beard,
|
||||
.face = face,
|
||||
.gender_id = gender_id,
|
||||
.hair = hair,
|
||||
.hair_color = hair_color,
|
||||
.helmet_texture = helmet_texture,
|
||||
.race_id = race_id,
|
||||
.texture = texture,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void Perl_Mob_SendIllusion(Mob* self, uint16 race, uint8 gender, uint8 texture, uint8 helmtexture, uint8 face, uint8 hairstyle, uint8 haircolor, uint8 beard, uint8 beardcolor) // @categories Script Utility
|
||||
void Perl_Mob_SendIllusion(
|
||||
Mob *self,
|
||||
uint16 race_id,
|
||||
uint8 gender_id,
|
||||
uint8 texture,
|
||||
uint8 helmet_texture,
|
||||
uint8 face,
|
||||
uint8 hair,
|
||||
uint8 hair_color,
|
||||
uint8 beard,
|
||||
uint8 beard_color
|
||||
) // @categories Script Utility
|
||||
{
|
||||
self->SendIllusionPacket(race, gender, texture, helmtexture, haircolor, beardcolor, 0xFF, 0xFF, hairstyle, face, beard);
|
||||
self->SendIllusionPacket(
|
||||
AppearanceStruct{
|
||||
.beard = beard,
|
||||
.beard_color = beard_color,
|
||||
.face = face,
|
||||
.gender_id = gender_id,
|
||||
.hair = hair,
|
||||
.hair_color = hair_color,
|
||||
.helmet_texture = helmet_texture,
|
||||
.race_id = race_id,
|
||||
.texture = texture,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void Perl_Mob_SendIllusion(Mob* self, uint16 race, uint8 gender, uint8 texture, uint8 helmtexture, uint8 face, uint8 hairstyle, uint8 haircolor, uint8 beard, uint8 beardcolor, uint32 drakkin_heritage) // @categories Script Utility
|
||||
void Perl_Mob_SendIllusion(
|
||||
Mob *self,
|
||||
uint16 race_id,
|
||||
uint8 gender_id,
|
||||
uint8 texture,
|
||||
uint8 helmet_texture,
|
||||
uint8 face,
|
||||
uint8 hair,
|
||||
uint8 hair_color,
|
||||
uint8 beard,
|
||||
uint8 beard_color,
|
||||
uint32 drakkin_heritage
|
||||
) // @categories Script Utility
|
||||
{
|
||||
self->SendIllusionPacket(race, gender, texture, helmtexture, haircolor, beardcolor, 0xFF, 0xFF, hairstyle, face, beard, 0xFF, drakkin_heritage);
|
||||
self->SendIllusionPacket(
|
||||
AppearanceStruct{
|
||||
.beard = beard,
|
||||
.beard_color = beard_color,
|
||||
.drakkin_heritage = drakkin_heritage,
|
||||
.face = face,
|
||||
.gender_id = gender_id,
|
||||
.hair = hair,
|
||||
.hair_color = hair_color,
|
||||
.helmet_texture = helmet_texture,
|
||||
.race_id = race_id,
|
||||
.texture = texture,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void Perl_Mob_SendIllusion(Mob* self, uint16 race, uint8 gender, uint8 texture, uint8 helmtexture, uint8 face, uint8 hairstyle, uint8 haircolor, uint8 beard, uint8 beardcolor, uint32 drakkin_heritage, uint32 drakkin_tattoo) // @categories Script Utility
|
||||
void Perl_Mob_SendIllusion(
|
||||
Mob *self,
|
||||
uint16 race_id,
|
||||
uint8 gender_id,
|
||||
uint8 texture,
|
||||
uint8 helmet_texture,
|
||||
uint8 face,
|
||||
uint8 hair,
|
||||
uint8 hair_color,
|
||||
uint8 beard,
|
||||
uint8 beard_color,
|
||||
uint32 drakkin_heritage,
|
||||
uint32 drakkin_tattoo
|
||||
) // @categories Script Utility
|
||||
{
|
||||
self->SendIllusionPacket(race, gender, texture, helmtexture, haircolor, beardcolor, 0xFF, 0xFF, hairstyle, face, beard, 0xFF, drakkin_heritage, drakkin_tattoo);
|
||||
self->SendIllusionPacket(
|
||||
AppearanceStruct{
|
||||
.beard = beard,
|
||||
.beard_color = beard_color,
|
||||
.drakkin_heritage = drakkin_heritage,
|
||||
.drakkin_tattoo = drakkin_tattoo,
|
||||
.face = face,
|
||||
.gender_id = gender_id,
|
||||
.hair = hair,
|
||||
.hair_color = hair_color,
|
||||
.helmet_texture = helmet_texture,
|
||||
.race_id = race_id,
|
||||
.texture = texture,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void Perl_Mob_SendIllusion(Mob* self, uint16 race, uint8 gender, uint8 texture, uint8 helmtexture, uint8 face, uint8 hairstyle, uint8 haircolor, uint8 beard, uint8 beardcolor, uint32 drakkin_heritage, uint32 drakkin_tattoo, uint32 drakkin_details) // @categories Script Utility
|
||||
void Perl_Mob_SendIllusion(
|
||||
Mob *self,
|
||||
uint16 race_id,
|
||||
uint8 gender_id,
|
||||
uint8 texture,
|
||||
uint8 helmet_texture,
|
||||
uint8 face,
|
||||
uint8 hair,
|
||||
uint8 hair_color,
|
||||
uint8 beard,
|
||||
uint8 beard_color,
|
||||
uint32 drakkin_heritage,
|
||||
uint32 drakkin_tattoo,
|
||||
uint32 drakkin_details
|
||||
) // @categories Script Utility
|
||||
{
|
||||
self->SendIllusionPacket(race, gender, texture, helmtexture, haircolor, beardcolor, 0xFF, 0xFF, hairstyle, face, beard, 0xFF, drakkin_heritage, drakkin_tattoo, drakkin_details);
|
||||
self->SendIllusionPacket(
|
||||
AppearanceStruct{
|
||||
.beard = beard,
|
||||
.beard_color = beard_color,
|
||||
.drakkin_details = drakkin_details,
|
||||
.drakkin_heritage = drakkin_heritage,
|
||||
.drakkin_tattoo = drakkin_tattoo,
|
||||
.face = face,
|
||||
.gender_id = gender_id,
|
||||
.hair = hair,
|
||||
.hair_color = hair_color,
|
||||
.helmet_texture = helmet_texture,
|
||||
.race_id = race_id,
|
||||
.texture = texture,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void Perl_Mob_SendIllusion(Mob* self, uint16 race, uint8 gender, uint8 texture, uint8 helmtexture, uint8 face, uint8 hairstyle, uint8 haircolor, uint8 beard, uint8 beardcolor, uint32 drakkin_heritage, uint32 drakkin_tattoo, uint32 drakkin_details, float size) // @categories Script Utility
|
||||
void Perl_Mob_SendIllusion(
|
||||
Mob *self,
|
||||
uint16 race_id,
|
||||
uint8 gender_id,
|
||||
uint8 texture,
|
||||
uint8 helmet_texture,
|
||||
uint8 face,
|
||||
uint8 hair,
|
||||
uint8 hair_color,
|
||||
uint8 beard,
|
||||
uint8 beard_color,
|
||||
uint32 drakkin_heritage,
|
||||
uint32 drakkin_tattoo,
|
||||
uint32 drakkin_details,
|
||||
float size
|
||||
) // @categories Script Utility
|
||||
{
|
||||
self->SendIllusionPacket(race, gender, texture, helmtexture, haircolor, beardcolor, 0xFF, 0xFF, hairstyle, face, beard, 0xFF, drakkin_heritage, drakkin_tattoo, drakkin_details, size);
|
||||
self->SendIllusionPacket(
|
||||
AppearanceStruct{
|
||||
.beard = beard,
|
||||
.beard_color = beard_color,
|
||||
.drakkin_details = drakkin_details,
|
||||
.drakkin_heritage = drakkin_heritage,
|
||||
.drakkin_tattoo = drakkin_tattoo,
|
||||
.face = face,
|
||||
.gender_id = gender_id,
|
||||
.hair = hair,
|
||||
.hair_color = hair_color,
|
||||
.helmet_texture = helmet_texture,
|
||||
.race_id = race_id,
|
||||
.size = size,
|
||||
.texture = texture,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void Perl_Mob_SendIllusion(Mob* self, uint16 race, uint8 gender, uint8 texture, uint8 helmtexture, uint8 face, uint8 hairstyle, uint8 haircolor, uint8 beard, uint8 beardcolor, uint32 drakkin_heritage, uint32 drakkin_tattoo, uint32 drakkin_details, float size, Client* target) // @categories Script Utility
|
||||
void Perl_Mob_SendIllusion(
|
||||
Mob *self,
|
||||
uint16 race_id,
|
||||
uint8 gender_id,
|
||||
uint8 texture,
|
||||
uint8 helmet_texture,
|
||||
uint8 face,
|
||||
uint8 hair,
|
||||
uint8 hair_color,
|
||||
uint8 beard,
|
||||
uint8 beard_color,
|
||||
uint32 drakkin_heritage,
|
||||
uint32 drakkin_tattoo,
|
||||
uint32 drakkin_details,
|
||||
float size,
|
||||
Client *target
|
||||
) // @categories Script Utility
|
||||
{
|
||||
self->SendIllusionPacket(race, gender, texture, helmtexture, haircolor, beardcolor, 0xFF, 0xFF, hairstyle, face, beard, 0xFF, drakkin_heritage, drakkin_tattoo, drakkin_details, size, true, target);
|
||||
self->SendIllusionPacket(
|
||||
AppearanceStruct{
|
||||
.beard = beard,
|
||||
.beard_color = beard_color,
|
||||
.drakkin_details = drakkin_details,
|
||||
.drakkin_heritage = drakkin_heritage,
|
||||
.drakkin_tattoo = drakkin_tattoo,
|
||||
.face = face,
|
||||
.gender_id = gender_id,
|
||||
.hair = hair,
|
||||
.hair_color = hair_color,
|
||||
.helmet_texture = helmet_texture,
|
||||
.race_id = race_id,
|
||||
.size = size,
|
||||
.target = target,
|
||||
.texture = texture,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void Perl_Mob_SendIllusionPacket(Mob* self, perl::reference table_ref)
|
||||
{
|
||||
perl::hash table = table_ref;
|
||||
|
||||
uint16 race = table.exists("race") ? table["race"] : self->GetRace();
|
||||
uint8 gender = table.exists("gender") ? table["gender"] : self->GetGender();
|
||||
uint8 texture = table.exists("texture") ? table["texture"] : self->GetTexture();
|
||||
uint8 helmtexture = table.exists("helmtexture") ? table["helmtexture"] : self->GetHelmTexture();
|
||||
uint8 haircolor = table.exists("haircolor") ? table["haircolor"] : self->GetHairColor();
|
||||
uint8 beardcolor = table.exists("beardcolor") ? table["beardcolor"] : self->GetBeardColor();
|
||||
uint8 eyecolor1 = table.exists("eyecolor1") ? table["eyecolor1"] : self->GetEyeColor1();
|
||||
uint8 eyecolor2 = table.exists("eyecolor2") ? table["eyecolor2"] : self->GetEyeColor2();
|
||||
uint8 hairstyle = table.exists("hairstyle") ? table["hairstyle"] : self->GetHairStyle();
|
||||
uint8 luclinface = table.exists("luclinface") ? table["luclinface"] : self->GetLuclinFace();
|
||||
uint8 beard = table.exists("beard") ? table["beard"] : self->GetBeard();
|
||||
uint8 aa_title = table.exists("aa_title") ? table["aa_title"] : 255;
|
||||
uint32 drakkin_heritage = table.exists("drakkin_heritage") ? table["drakkin_heritage"] : self->GetDrakkinHeritage();
|
||||
uint32 drakkin_tattoo = table.exists("drakkin_tattoo") ? table["drakkin_tattoo"] : self->GetDrakkinTattoo();
|
||||
uint32 drakkin_details = table.exists("drakkin_details") ? table["drakkin_details"] : self->GetDrakkinDetails();
|
||||
float size = table.exists("size") ? table["size"] : self->GetSize();
|
||||
bool send_appearance_effects = table.exists("send_appearance_effects") ? table["send_appearance_effects"] : true;
|
||||
Client* target = table.exists("target") ? static_cast<Client *>(table["target"]) : nullptr;
|
||||
uint16 race_id = table.exists("race") ? table["race"] : self->GetRace();
|
||||
uint8 gender_id = table.exists("gender") ? table["gender"] : self->GetGender();
|
||||
uint8 texture = table.exists("texture") ? table["texture"] : self->GetTexture();
|
||||
uint8 helmet_texture = table.exists("helmtexture") ? table["helmtexture"] : self->GetHelmTexture();
|
||||
uint8 hair_color = table.exists("haircolor") ? table["haircolor"] : self->GetHairColor();
|
||||
uint8 beard_color = table.exists("beardcolor") ? table["beardcolor"] : self->GetBeardColor();
|
||||
uint8 eye_color_one = table.exists("eyecolor1") ? table["eyecolor1"] : self->GetEyeColor1();
|
||||
uint8 eye_color_two = table.exists("eyecolor2") ? table["eyecolor2"] : self->GetEyeColor2();
|
||||
uint8 hair = table.exists("hairstyle") ? table["hairstyle"] : self->GetHairStyle();
|
||||
uint8 face = table.exists("luclinface") ? table["luclinface"] : self->GetLuclinFace();
|
||||
uint8 beard = table.exists("beard") ? table["beard"] : self->GetBeard();
|
||||
uint8 aa_title = table.exists("aa_title") ? table["aa_title"] : 255;
|
||||
uint32 drakkin_heritage = table.exists("drakkin_heritage") ? table["drakkin_heritage"] : self->GetDrakkinHeritage();
|
||||
uint32 drakkin_tattoo = table.exists("drakkin_tattoo") ? table["drakkin_tattoo"] : self->GetDrakkinTattoo();
|
||||
uint32 drakkin_details = table.exists("drakkin_details") ? table["drakkin_details"] : self->GetDrakkinDetails();
|
||||
float size = table.exists("size") ? table["size"] : self->GetSize();
|
||||
bool send_appearance_effects = table.exists("send_appearance_effects") ? table["send_appearance_effects"] : true;
|
||||
|
||||
Client *target = table.exists("target") ? static_cast<Client *>(table["target"]) : nullptr;
|
||||
|
||||
self->SendIllusionPacket(
|
||||
race,
|
||||
gender,
|
||||
texture,
|
||||
helmtexture,
|
||||
haircolor,
|
||||
beardcolor,
|
||||
eyecolor1,
|
||||
eyecolor2,
|
||||
hairstyle,
|
||||
luclinface,
|
||||
beard,
|
||||
aa_title,
|
||||
drakkin_heritage,
|
||||
drakkin_tattoo,
|
||||
drakkin_details,
|
||||
size,
|
||||
send_appearance_effects,
|
||||
target
|
||||
AppearanceStruct{
|
||||
.beard = beard,
|
||||
.beard_color = beard_color,
|
||||
.drakkin_details = drakkin_details,
|
||||
.drakkin_heritage = drakkin_heritage,
|
||||
.drakkin_tattoo = drakkin_tattoo,
|
||||
.face = face,
|
||||
.gender_id = gender_id,
|
||||
.hair = hair,
|
||||
.hair_color = hair_color,
|
||||
.helmet_texture = helmet_texture,
|
||||
.race_id = race_id,
|
||||
.send_effects = send_appearance_effects,
|
||||
.size = size,
|
||||
.target = target,
|
||||
.texture = texture,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
+78
-48
@@ -2187,7 +2187,7 @@ bool QuestManager::isdooropen(uint32 doorid) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void QuestManager::npcrace(int race_id)
|
||||
void QuestManager::npcrace(uint16 race_id)
|
||||
{
|
||||
QuestManagerCurrentQuestVars();
|
||||
|
||||
@@ -2195,10 +2195,14 @@ void QuestManager::npcrace(int race_id)
|
||||
return;
|
||||
}
|
||||
|
||||
owner->SendIllusionPacket(race_id);
|
||||
owner->SendIllusionPacket(
|
||||
AppearanceStruct{
|
||||
.race_id = race_id,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void QuestManager::npcgender(int gender_id)
|
||||
void QuestManager::npcgender(uint8 gender_id)
|
||||
{
|
||||
QuestManagerCurrentQuestVars();
|
||||
|
||||
@@ -2206,10 +2210,15 @@ void QuestManager::npcgender(int gender_id)
|
||||
return;
|
||||
}
|
||||
|
||||
owner->SendIllusionPacket(owner->GetRace(), gender_id);
|
||||
owner->SendIllusionPacket(
|
||||
AppearanceStruct{
|
||||
.gender_id = gender_id,
|
||||
.race_id = owner->GetRace(),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void QuestManager::npcsize(int newsize)
|
||||
void QuestManager::npcsize(float size)
|
||||
{
|
||||
QuestManagerCurrentQuestVars();
|
||||
|
||||
@@ -2217,10 +2226,10 @@ void QuestManager::npcsize(int newsize)
|
||||
return;
|
||||
}
|
||||
|
||||
owner->ChangeSize(newsize, true);
|
||||
owner->ChangeSize(size, true);
|
||||
}
|
||||
|
||||
void QuestManager::npctexture(int newtexture)
|
||||
void QuestManager::npctexture(uint8 texture)
|
||||
{
|
||||
QuestManagerCurrentQuestVars();
|
||||
|
||||
@@ -2228,10 +2237,15 @@ void QuestManager::npctexture(int newtexture)
|
||||
return;
|
||||
}
|
||||
|
||||
owner->SendIllusionPacket(owner->GetRace(), 0xFF, newtexture);
|
||||
owner->SendIllusionPacket(
|
||||
AppearanceStruct{
|
||||
.race_id = owner->GetRace(),
|
||||
.texture = texture,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void QuestManager::playerrace(int race_id)
|
||||
void QuestManager::playerrace(uint16 race_id)
|
||||
{
|
||||
QuestManagerCurrentQuestVars();
|
||||
|
||||
@@ -2239,10 +2253,14 @@ void QuestManager::playerrace(int race_id)
|
||||
return;
|
||||
}
|
||||
|
||||
initiator->SendIllusionPacket(race_id);
|
||||
initiator->SendIllusionPacket(
|
||||
AppearanceStruct{
|
||||
.race_id = race_id,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void QuestManager::playergender(int gender_id)
|
||||
void QuestManager::playergender(uint8 gender_id)
|
||||
{
|
||||
QuestManagerCurrentQuestVars();
|
||||
|
||||
@@ -2250,10 +2268,15 @@ void QuestManager::playergender(int gender_id)
|
||||
return;
|
||||
}
|
||||
|
||||
initiator->SendIllusionPacket(initiator->GetRace(), gender_id);
|
||||
initiator->SendIllusionPacket(
|
||||
AppearanceStruct{
|
||||
.gender_id = gender_id,
|
||||
.race_id = initiator->GetRace(),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void QuestManager::playersize(int newsize)
|
||||
void QuestManager::playersize(float size)
|
||||
{
|
||||
QuestManagerCurrentQuestVars();
|
||||
|
||||
@@ -2261,10 +2284,10 @@ void QuestManager::playersize(int newsize)
|
||||
return;
|
||||
}
|
||||
|
||||
initiator->ChangeSize(newsize, true);
|
||||
initiator->ChangeSize(size, true);
|
||||
}
|
||||
|
||||
void QuestManager::playertexture(int newtexture)
|
||||
void QuestManager::playertexture(uint8 texture)
|
||||
{
|
||||
QuestManagerCurrentQuestVars();
|
||||
|
||||
@@ -2272,7 +2295,12 @@ void QuestManager::playertexture(int newtexture)
|
||||
return;
|
||||
}
|
||||
|
||||
initiator->SendIllusionPacket(initiator->GetRace(), 0xFF, newtexture);
|
||||
initiator->SendIllusionPacket(
|
||||
AppearanceStruct{
|
||||
.race_id = initiator->GetRace(),
|
||||
.texture = texture,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void QuestManager::playerfeature(const char* feature, int setting)
|
||||
@@ -2334,22 +2362,23 @@ void QuestManager::playerfeature(const char* feature, int setting)
|
||||
}
|
||||
|
||||
initiator->SendIllusionPacket(
|
||||
Race,
|
||||
Gender,
|
||||
Texture,
|
||||
HelmTexture,
|
||||
HairColor,
|
||||
BeardColor,
|
||||
EyeColor1,
|
||||
EyeColor2,
|
||||
HairStyle,
|
||||
LuclinFace,
|
||||
Beard,
|
||||
0xFF,
|
||||
DrakkinHeritage,
|
||||
DrakkinTattoo,
|
||||
DrakkinDetails,
|
||||
Size
|
||||
AppearanceStruct{
|
||||
.beard = Beard,
|
||||
.beard_color = BeardColor,
|
||||
.drakkin_details = DrakkinDetails,
|
||||
.drakkin_heritage = DrakkinHeritage,
|
||||
.drakkin_tattoo = DrakkinTattoo,
|
||||
.eye_color_one = EyeColor1,
|
||||
.eye_color_two = EyeColor2,
|
||||
.face = LuclinFace,
|
||||
.gender_id = Gender,
|
||||
.hair = HairStyle,
|
||||
.hair_color = HairColor,
|
||||
.helmet_texture = HelmTexture,
|
||||
.race_id = Race,
|
||||
.size = Size,
|
||||
.texture = Texture,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2412,22 +2441,23 @@ void QuestManager::npcfeature(const char* feature, int setting)
|
||||
}
|
||||
|
||||
owner->SendIllusionPacket(
|
||||
Race,
|
||||
Gender,
|
||||
Texture,
|
||||
HelmTexture,
|
||||
HairColor,
|
||||
BeardColor,
|
||||
EyeColor1,
|
||||
EyeColor2,
|
||||
HairStyle,
|
||||
LuclinFace,
|
||||
Beard,
|
||||
0xFF,
|
||||
DrakkinHeritage,
|
||||
DrakkinTattoo,
|
||||
DrakkinDetails,
|
||||
Size
|
||||
AppearanceStruct{
|
||||
.beard = Beard,
|
||||
.beard_color = BeardColor,
|
||||
.drakkin_details = DrakkinDetails,
|
||||
.drakkin_heritage = DrakkinHeritage,
|
||||
.drakkin_tattoo = DrakkinTattoo,
|
||||
.eye_color_one = EyeColor1,
|
||||
.eye_color_two = EyeColor2,
|
||||
.face = LuclinFace,
|
||||
.gender_id = Gender,
|
||||
.hair = HairStyle,
|
||||
.hair_color = HairColor,
|
||||
.helmet_texture = HelmTexture,
|
||||
.race_id = Race,
|
||||
.size = Size,
|
||||
.texture = Texture,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
+8
-7
@@ -201,13 +201,14 @@ public:
|
||||
void forcedoorclose(uint32 doorid, bool altmode);
|
||||
void toggledoorstate(uint32 doorid);
|
||||
bool isdooropen(uint32 doorid);
|
||||
void npcrace(int race_id);
|
||||
void npcgender(int gender_id); void npcsize(int newsize);
|
||||
void npctexture(int newtexture);
|
||||
void playerrace(int race_id);
|
||||
void playergender(int gender_id);
|
||||
void playersize(int newsize);
|
||||
void playertexture(int newtexture);
|
||||
void npcrace(uint16 race_id);
|
||||
void npcgender(uint8 gender_id);
|
||||
void npcsize(float size);
|
||||
void npctexture(uint8 texture);
|
||||
void playerrace(uint16 race_id);
|
||||
void playergender(uint8 gender_id);
|
||||
void playersize(float size);
|
||||
void playertexture(uint8 texture);
|
||||
void playerfeature(const char* feature, int setting);
|
||||
void npcfeature(const char* feature, int setting);
|
||||
void popup(const char *title, const char *text, uint32 popupid, uint32 buttons, uint32 Duration);
|
||||
|
||||
+49
-28
@@ -55,7 +55,9 @@ Raid::Raid(uint32 raidID)
|
||||
for (int i = 0; i < MAX_NO_RAID_MAIN_ASSISTERS; i++) {
|
||||
memset(main_assister_pcs[i], 0, 64);
|
||||
memset(main_marker_pcs[i], 0, 64);
|
||||
marked_npcs[i] = 0;
|
||||
marked_npcs[i].entity_id = 0;
|
||||
marked_npcs[i].zone_id = 0;
|
||||
marked_npcs[i].instance_id = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,7 +82,9 @@ Raid::Raid(Client* nLeader)
|
||||
for (int i = 0; i < MAX_NO_RAID_MAIN_ASSISTERS; i++) {
|
||||
memset(main_assister_pcs[i], 0, 64);
|
||||
memset(main_marker_pcs[i], 0, 64);
|
||||
marked_npcs[i] = 0;
|
||||
marked_npcs[i].entity_id = 0;
|
||||
marked_npcs[i].zone_id = 0;
|
||||
marked_npcs[i].instance_id = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1678,9 +1682,15 @@ void Raid::GetRaidDetails()
|
||||
locked = raid_details.locked;
|
||||
LootType = raid_details.loottype;
|
||||
motd = raid_details.motd;
|
||||
marked_npcs[0] = raid_details.marked_npc_1;
|
||||
marked_npcs[1] = raid_details.marked_npc_2;
|
||||
marked_npcs[2] = raid_details.marked_npc_3;
|
||||
marked_npcs[0].entity_id = raid_details.marked_npc_1_entity_id;
|
||||
marked_npcs[0].zone_id = raid_details.marked_npc_1_zone_id;
|
||||
marked_npcs[0].instance_id = raid_details.marked_npc_1_instance_id;
|
||||
marked_npcs[1].entity_id = raid_details.marked_npc_2_entity_id;
|
||||
marked_npcs[1].zone_id = raid_details.marked_npc_2_zone_id;
|
||||
marked_npcs[1].instance_id = raid_details.marked_npc_2_instance_id;
|
||||
marked_npcs[2].entity_id = raid_details.marked_npc_3_entity_id;
|
||||
marked_npcs[2].zone_id = raid_details.marked_npc_3_zone_id;
|
||||
marked_npcs[2].instance_id = raid_details.marked_npc_3_instance_id;
|
||||
}
|
||||
|
||||
void Raid::SaveRaidMOTD()
|
||||
@@ -2419,8 +2429,8 @@ void Raid::UpdateRaidXTargets()
|
||||
};
|
||||
|
||||
for (auto& u : marked_updates) {
|
||||
if (marked_npcs[u.slot]) {
|
||||
auto m = entity_list.GetMob(marked_npcs[u.slot]);
|
||||
if (marked_npcs[u.slot].entity_id) {
|
||||
auto m = entity_list.GetMob(marked_npcs[u.slot].entity_id);
|
||||
if (m && m->GetHP() > 0) {
|
||||
UpdateXTargetType(u.mark_target, m, m->GetName());
|
||||
}
|
||||
@@ -2562,13 +2572,17 @@ void Raid::RaidMarkNPC(Mob* mob, uint32 parameter)
|
||||
for (int i = 0; i < MAX_NO_RAID_MAIN_MARKERS; i++) {
|
||||
auto cname = c->GetCleanName();
|
||||
if (strcasecmp(main_marker_pcs[i], cname) == 0 || strcasecmp(leadername, cname) == 0) {
|
||||
marked_npcs[parameter - 1] = c->GetTarget()->GetID();
|
||||
marked_npcs[parameter - 1].entity_id = c->GetTarget()->GetID();
|
||||
marked_npcs[parameter - 1].zone_id = c->GetTarget()->GetZoneID();
|
||||
marked_npcs[parameter - 1].instance_id = c->GetTarget()->GetInstanceVersion();
|
||||
auto result = RaidDetailsRepository::UpdateRaidMarkedNPC(
|
||||
database,
|
||||
GetID(),
|
||||
parameter,
|
||||
marked_npcs[parameter - 1]
|
||||
);
|
||||
marked_npcs[parameter - 1].entity_id,
|
||||
marked_npcs[parameter - 1].zone_id,
|
||||
marked_npcs[parameter - 1].instance_id,
|
||||
parameter
|
||||
);
|
||||
if (!result) {
|
||||
LogError("Unable to set MarkedNPC{} from slot: [{}] for guild [{}].",
|
||||
parameter,
|
||||
@@ -2579,7 +2593,7 @@ void Raid::RaidMarkNPC(Mob* mob, uint32 parameter)
|
||||
|
||||
auto outapp = new EQApplicationPacket(OP_MarkRaidNPC, sizeof(MarkNPC_Struct));
|
||||
MarkNPC_Struct* mnpcs = (MarkNPC_Struct*)outapp->pBuffer;
|
||||
mnpcs->TargetID = marked_npcs[parameter - 1];
|
||||
mnpcs->TargetID = marked_npcs[parameter - 1].entity_id;
|
||||
mnpcs->Number = parameter;
|
||||
strcpy(mnpcs->Name, c->GetTarget()->GetCleanName());
|
||||
QueuePacket(outapp);
|
||||
@@ -2596,7 +2610,7 @@ void Raid::RaidMarkNPC(Mob* mob, uint32 parameter)
|
||||
void Raid::UpdateXtargetMarkedNPC()
|
||||
{
|
||||
for (int i = 0; i < MAX_MARKED_NPCS; i++) {
|
||||
auto mm = entity_list.GetNPCByID(marked_npcs[i]);
|
||||
auto mm = entity_list.GetNPCByID(marked_npcs[i].entity_id);
|
||||
if (mm) {
|
||||
UpdateXTargetType(static_cast<XTargetType>(RaidMarkTarget1 + i), mm->CastToMob(), mm->CastToMob()->GetName());
|
||||
}
|
||||
@@ -2614,19 +2628,25 @@ void Raid::RaidClearNPCMarks(Client* c)
|
||||
Strings::EqualFold(main_marker_pcs[MAIN_MARKER_2_SLOT], c->GetCleanName()) ||
|
||||
Strings::EqualFold(main_marker_pcs[MAIN_MARKER_3_SLOT], c->GetCleanName())) {
|
||||
for (int i = 0; i < MAX_MARKED_NPCS; i++) {
|
||||
if (marked_npcs[i]) {
|
||||
auto npc_name = entity_list.GetNPCByID(marked_npcs[i])->GetCleanName();
|
||||
if (marked_npcs[i].entity_id > 0 && marked_npcs[i].zone_id == c->GetZoneID()
|
||||
&& marked_npcs[i].instance_id == c->GetInstanceID())
|
||||
{
|
||||
auto npc_name = entity_list.GetNPCByID(marked_npcs[i].entity_id)->GetCleanName();
|
||||
RaidMessageString(nullptr, Chat::Cyan, RAID_NO_LONGER_MARKED, npc_name);
|
||||
}
|
||||
marked_npcs[i] = 0;
|
||||
auto result = RaidDetailsRepository::UpdateRaidMarkedNPC(
|
||||
database,
|
||||
GetID(),
|
||||
i + 1,
|
||||
0
|
||||
);
|
||||
if (!result) {
|
||||
LogError("Unable to clear MarkedNPC{} from slot: [{}] for guild [{}].", i + 1, i, GetID());
|
||||
marked_npcs[i].entity_id = 0;
|
||||
marked_npcs[i].zone_id = 0;
|
||||
marked_npcs[i].instance_id = 0;
|
||||
auto result = RaidDetailsRepository::UpdateRaidMarkedNPC(
|
||||
database,
|
||||
GetID(),
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
i + 1
|
||||
);
|
||||
if (!result) {
|
||||
LogError("Unable to clear MarkedNPC{} from slot: [{}] for guild [{}].", i + 1, i, GetID());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2934,12 +2954,13 @@ void Raid::SendMarkTargets(Client* c)
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_MARKED_NPCS; i++) {
|
||||
if (marked_npcs[i] > 0) {
|
||||
auto marked_mob = entity_list.GetMob(marked_npcs[i]);
|
||||
if (marked_npcs[i].entity_id > 0 && marked_npcs[i].zone_id == c->GetZoneID()
|
||||
&& marked_npcs[i].instance_id == c->GetInstanceID()) {
|
||||
auto marked_mob = entity_list.GetMob(marked_npcs[i].entity_id);
|
||||
if (marked_mob) {
|
||||
auto outapp = new EQApplicationPacket(OP_MarkRaidNPC, sizeof(MarkNPC_Struct));
|
||||
MarkNPC_Struct* mnpcs = (MarkNPC_Struct*)outapp->pBuffer;
|
||||
mnpcs->TargetID = marked_npcs[i];
|
||||
mnpcs->TargetID = marked_mob->GetID();
|
||||
mnpcs->Number = i + 1;
|
||||
strcpy(mnpcs->Name, marked_mob->GetCleanName());
|
||||
QueuePacket(outapp);
|
||||
|
||||
+7
-1
@@ -110,6 +110,12 @@ enum {
|
||||
DELEGATE_ON = 1
|
||||
};
|
||||
|
||||
struct Raid_Marked_NPC {
|
||||
uint32 entity_id;
|
||||
uint32 zone_id;
|
||||
uint32 instance_id;
|
||||
};
|
||||
|
||||
|
||||
constexpr uint8_t MAX_RAID_GROUPS = 12;
|
||||
constexpr uint8_t MAX_RAID_MEMBERS = 72;
|
||||
@@ -326,7 +332,7 @@ public:
|
||||
char leadername[64];
|
||||
char main_assister_pcs[MAX_NO_RAID_MAIN_ASSISTERS][64];
|
||||
char main_marker_pcs[MAX_NO_RAID_MAIN_MARKERS][64];
|
||||
uint32 marked_npcs[MAX_MARKED_NPCS];
|
||||
Raid_Marked_NPC marked_npcs[MAX_MARKED_NPCS];
|
||||
protected:
|
||||
Client *leader;
|
||||
bool locked;
|
||||
|
||||
+4
-2
@@ -26,6 +26,7 @@
|
||||
#include "worldserver.h"
|
||||
#include "zone.h"
|
||||
#include "zonedb.h"
|
||||
#include "../common/repositories/criteria/content_filter_criteria.h"
|
||||
|
||||
extern EntityList entity_list;
|
||||
extern Zone* zone;
|
||||
@@ -467,7 +468,7 @@ bool ZoneDatabase::PopulateZoneSpawnList(uint32 zoneid, LinkedList<Spawn2*> &spa
|
||||
LogInfo("Loaded [{}] respawn timer(s)", Strings::Commify(results.RowCount()));
|
||||
|
||||
const char *zone_name = ZoneName(zoneid);
|
||||
std::string query = StringFormat(
|
||||
std::string query = fmt::format(
|
||||
"SELECT "
|
||||
"id, "
|
||||
"spawngroupID, "
|
||||
@@ -485,7 +486,8 @@ bool ZoneDatabase::PopulateZoneSpawnList(uint32 zoneid, LinkedList<Spawn2*> &spa
|
||||
"animation "
|
||||
"FROM "
|
||||
"spawn2 "
|
||||
"WHERE zone = '%s' AND (version = %u OR version = -1)",
|
||||
"WHERE TRUE {} AND zone = '{}' AND (version = {} OR version = -1) ",
|
||||
ContentFilterCriteria::apply(),
|
||||
zone_name,
|
||||
version
|
||||
);
|
||||
|
||||
+94
-56
@@ -799,6 +799,12 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
||||
|
||||
SetPetType(petCharmed);
|
||||
|
||||
// This was done in AddBuff, but we were not a pet yet, so
|
||||
// the target windows didn't get updated.
|
||||
EQApplicationPacket *outapp = MakeBuffsPacket();
|
||||
entity_list.QueueClientsByTarget(this, outapp, false, nullptr, true, false, EQ::versions::maskSoDAndLater);
|
||||
safe_delete(outapp);
|
||||
|
||||
if(caster->IsClient()){
|
||||
auto app = new EQApplicationPacket(OP_Charm, sizeof(Charm_Struct));
|
||||
Charm_Struct *ps = (Charm_Struct*)app->pBuffer;
|
||||
@@ -1474,9 +1480,11 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
|
||||
if(caster && caster->GetTarget()){
|
||||
SendIllusionPacket
|
||||
(
|
||||
caster->GetTarget()->GetRace(),
|
||||
caster->GetTarget()->GetGender(),
|
||||
caster->GetTarget()->GetTexture()
|
||||
AppearanceStruct{
|
||||
.gender_id = caster->GetTarget()->GetGender(),
|
||||
.race_id = caster->GetTarget()->GetRace(),
|
||||
.texture = caster->GetTarget()->GetTexture(),
|
||||
}
|
||||
);
|
||||
caster->SendAppearancePacket(AT_Size, static_cast<uint32>(caster->GetTarget()->GetSize()));
|
||||
|
||||
@@ -4265,7 +4273,7 @@ void Mob::BuffFadeBySlot(int slot, bool iRecalcBonuses)
|
||||
case SE_IllusionCopy:
|
||||
case SE_Illusion:
|
||||
{
|
||||
SendIllusionPacket(0, GetBaseGender());
|
||||
SendIllusionPacket(AppearanceStruct{});
|
||||
// The GetSize below works because the above setting race to zero sets size back.
|
||||
SendAppearancePacket(AT_Size, GetSize());
|
||||
|
||||
@@ -4353,6 +4361,15 @@ void Mob::BuffFadeBySlot(int slot, bool iRecalcBonuses)
|
||||
{
|
||||
owner->SetPet(0);
|
||||
}
|
||||
|
||||
// Any client that has a previous charmed pet targetted shouldo
|
||||
// no longer see the buffs on the old pet.
|
||||
// QueueClientsByTarget preserves GM and leadership cases.
|
||||
|
||||
EQApplicationPacket *outapp = MakeBuffsPacket(true, true);
|
||||
|
||||
entity_list.QueueClientsByTarget(this, outapp, false, nullptr, true, false, EQ::versions::maskSoDAndLater, true, true);
|
||||
|
||||
if (IsAIControlled())
|
||||
{
|
||||
//Remove damage over time effects on charmed pet and those applied by charmed pet.
|
||||
@@ -10199,36 +10216,29 @@ void Mob::ApplySpellEffectIllusion(int32 spell_id, Mob *caster, int buffslot, in
|
||||
if (base == -1) {
|
||||
// Specific Gender Illusions
|
||||
if (spell_id == SPELL_ILLUSION_MALE || spell_id == SPELL_ILLUSION_FEMALE) {
|
||||
int specific_gender = -1;
|
||||
// Male
|
||||
if (spell_id == SPELL_ILLUSION_MALE)
|
||||
specific_gender = 0;
|
||||
// Female
|
||||
else if (spell_id == SPELL_ILLUSION_FEMALE)
|
||||
specific_gender = 1;
|
||||
if (specific_gender > -1) {
|
||||
if (caster && caster->GetTarget()) {
|
||||
SendIllusionPacket
|
||||
(
|
||||
caster->GetTarget()->GetBaseRace(),
|
||||
specific_gender,
|
||||
caster->GetTarget()->GetTexture()
|
||||
);
|
||||
}
|
||||
uint8 specific_gender = spell_id == SPELL_ILLUSION_MALE ? MALE : FEMALE;
|
||||
|
||||
if (caster && caster->GetTarget()) {
|
||||
SendIllusionPacket(
|
||||
AppearanceStruct{
|
||||
.gender_id = specific_gender,
|
||||
.race_id = caster->GetTarget()->GetBaseRace(),
|
||||
.texture = caster->GetTarget()->GetTexture(),
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
// Change Gender Illusions
|
||||
// Change Gender Illusions
|
||||
else {
|
||||
if (caster && caster->GetTarget()) {
|
||||
int opposite_gender = 0;
|
||||
if (caster->GetTarget()->GetGender() == 0)
|
||||
opposite_gender = 1;
|
||||
uint8 opposite_gender = caster->GetTarget()->GetGender() == MALE ? FEMALE : MALE;
|
||||
|
||||
SendIllusionPacket
|
||||
(
|
||||
caster->GetTarget()->GetRace(),
|
||||
opposite_gender,
|
||||
caster->GetTarget()->GetTexture()
|
||||
SendIllusionPacket(
|
||||
AppearanceStruct{
|
||||
.gender_id = opposite_gender,
|
||||
.race_id = caster->GetTarget()->GetRace(),
|
||||
.texture = caster->GetTarget()->GetTexture(),
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -10250,50 +10260,78 @@ void Mob::ApplySpellEffectIllusion(int32 spell_id, Mob *caster, int buffslot, in
|
||||
gender_id
|
||||
);
|
||||
|
||||
if (base != RACE_ELEMENTAL_75) {
|
||||
if (base != RACE_ELEMENTAL_75 && base != RACE_DRAKKIN_522) {
|
||||
if (max > 0) {
|
||||
if (limit == 0) {
|
||||
SendIllusionPacket(
|
||||
base,
|
||||
gender_id
|
||||
AppearanceStruct{
|
||||
.gender_id = static_cast<uint8>(gender_id),
|
||||
.race_id = static_cast<uint16>(base),
|
||||
}
|
||||
);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if (max != 3) {
|
||||
SendIllusionPacket(
|
||||
base,
|
||||
gender_id,
|
||||
limit,
|
||||
max
|
||||
AppearanceStruct{
|
||||
.gender_id = static_cast<uint8>(gender_id),
|
||||
.helmet_texture = static_cast<uint8>(max),
|
||||
.race_id = static_cast<uint16>(base),
|
||||
.texture = static_cast<uint8>(limit),
|
||||
}
|
||||
);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
SendIllusionPacket(
|
||||
base,
|
||||
gender_id,
|
||||
limit,
|
||||
limit
|
||||
AppearanceStruct{
|
||||
.gender_id = static_cast<uint8>(gender_id),
|
||||
.helmet_texture = static_cast<uint8>(limit),
|
||||
.race_id = static_cast<uint16>(base),
|
||||
.texture = static_cast<uint8>(limit),
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
SendIllusionPacket(
|
||||
base,
|
||||
gender_id,
|
||||
limit,
|
||||
max
|
||||
AppearanceStruct{
|
||||
.gender_id = static_cast<uint8>(gender_id),
|
||||
.helmet_texture = static_cast<uint8>(max),
|
||||
.race_id = static_cast<uint16>(base),
|
||||
.texture = static_cast<uint8>(limit),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
} else if (base == RACE_ELEMENTAL_75){
|
||||
SendIllusionPacket(
|
||||
base,
|
||||
gender_id,
|
||||
limit
|
||||
AppearanceStruct{
|
||||
.gender_id = static_cast<uint8>(gender_id),
|
||||
.race_id = static_cast<uint16>(base),
|
||||
.texture = static_cast<uint8>(limit),
|
||||
}
|
||||
);
|
||||
} else if (base == RACE_DRAKKIN_522) {
|
||||
FaceChange_Struct f{
|
||||
.haircolor = GetHairColor(),
|
||||
.beardcolor = GetBeardColor(),
|
||||
.eyecolor1 = GetEyeColor1(),
|
||||
.eyecolor2 = GetEyeColor2(),
|
||||
.hairstyle = GetHairStyle(),
|
||||
.beard = GetBeard(),
|
||||
.face = GetLuclinFace(),
|
||||
.drakkin_heritage = static_cast<uint32>(limit),
|
||||
.drakkin_tattoo = GetDrakkinTattoo(),
|
||||
.drakkin_details = GetDrakkinDetails(),
|
||||
};
|
||||
|
||||
SendIllusionPacket(
|
||||
AppearanceStruct{
|
||||
.gender_id = static_cast<uint8>(gender_id),
|
||||
.race_id = static_cast<uint16>(base),
|
||||
}
|
||||
);
|
||||
|
||||
SetFaceAppearance(f);
|
||||
}
|
||||
|
||||
SendAppearancePacket(AT_Size, race_size);
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user