mirror of
https://github.com/EQEmu/Server.git
synced 2026-03-31 06:12:28 +00:00
Merge branch 'master' into shared_tasks
This commit is contained in:
commit
7286e6a37f
@ -1,5 +1,20 @@
|
|||||||
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
|
== 12/15/2018 ==
|
||||||
|
Kinglykrab: Added multiple new instance related quest functions.
|
||||||
|
1. quest::GetInstanceIDByCharID(const char *zone, int16 version, uint32 char_id)
|
||||||
|
- Allows you to pull the instance ID of a client by character ID.
|
||||||
|
2. quest::AssignToInstanceByCharID(uint16 instance_id, uint32 char_id)
|
||||||
|
- Allows you to assign an instance to a client by character ID.
|
||||||
|
3. quest::RemoveFromInstanceByCharID(uint16 instance_id, uint32 char_id)
|
||||||
|
- Allows you to remove a client from an instance by character ID.
|
||||||
|
|
||||||
|
Added spell buckets, similar to spell globals.
|
||||||
|
- Uses a new spell_buckets table and the Spells:EnableSpellBuckets rule.
|
||||||
|
|
||||||
|
Added max level by data bucket.
|
||||||
|
- Uses data bucket char_id-CharMaxLevel and Character:PerCharacterBucketMaxLevel rule.
|
||||||
|
|
||||||
== 10/09/2018 ==
|
== 10/09/2018 ==
|
||||||
Uleat: Added bot owner options
|
Uleat: Added bot owner options
|
||||||
- usage: ^owneroption [option] (or aliased as: ^oo [option])
|
- usage: ^owneroption [option] (or aliased as: ^oo [option])
|
||||||
|
|||||||
@ -2080,7 +2080,6 @@ void Database::LoadLogSettings(EQEmuLogSys::LogSettings* log_settings) {
|
|||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
|
|
||||||
int log_category_id = 0;
|
int log_category_id = 0;
|
||||||
LogSys.file_logs_enabled = false;
|
|
||||||
|
|
||||||
int categories_in_database[1000] = {};
|
int categories_in_database[1000] = {};
|
||||||
|
|
||||||
@ -2090,9 +2089,9 @@ void Database::LoadLogSettings(EQEmuLogSys::LogSettings* log_settings) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
log_settings[log_category_id].log_to_console = atoi(row[2]);
|
log_settings[log_category_id].log_to_console = static_cast<uint8>(atoi(row[2]));
|
||||||
log_settings[log_category_id].log_to_file = atoi(row[3]);
|
log_settings[log_category_id].log_to_file = static_cast<uint8>(atoi(row[3]));
|
||||||
log_settings[log_category_id].log_to_gmsay = atoi(row[4]);
|
log_settings[log_category_id].log_to_gmsay = static_cast<uint8>(atoi(row[4]));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine if any output method is enabled for the category
|
* Determine if any output method is enabled for the category
|
||||||
|
|||||||
@ -306,7 +306,6 @@ union
|
|||||||
uint32 DestructibleUnk9;
|
uint32 DestructibleUnk9;
|
||||||
bool targetable_with_hotkey;
|
bool targetable_with_hotkey;
|
||||||
bool show_name;
|
bool show_name;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PlayerState_Struct {
|
struct PlayerState_Struct {
|
||||||
|
|||||||
@ -113,6 +113,15 @@ void EQEmuLogSys::LoadLogSettingsDefaults()
|
|||||||
*/
|
*/
|
||||||
log_platform = GetExecutablePlatformInt();
|
log_platform = GetExecutablePlatformInt();
|
||||||
|
|
||||||
|
for (int log_category_id = Logs::AA; log_category_id != Logs::MaxCategoryID; log_category_id++) {
|
||||||
|
log_settings[log_category_id].log_to_console = 0;
|
||||||
|
log_settings[log_category_id].log_to_file = 0;
|
||||||
|
log_settings[log_category_id].log_to_gmsay = 0;
|
||||||
|
log_settings[log_category_id].is_category_enabled = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
file_logs_enabled = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Zero out Array
|
* Zero out Array
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -350,4 +350,5 @@ bool EQ::Net::StaticPacket::Resize(size_t new_size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_data_length = new_size;
|
m_data_length = new_size;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
@ -38,6 +38,7 @@
|
|||||||
RULE_CATEGORY(Character)
|
RULE_CATEGORY(Character)
|
||||||
RULE_INT(Character, MaxLevel, 65)
|
RULE_INT(Character, MaxLevel, 65)
|
||||||
RULE_BOOL(Character, PerCharacterQglobalMaxLevel, false) // This will check for qglobal 'CharMaxLevel' character qglobal (Type 5), if player tries to level beyond that point, it will not go beyond that level
|
RULE_BOOL(Character, PerCharacterQglobalMaxLevel, false) // This will check for qglobal 'CharMaxLevel' character qglobal (Type 5), if player tries to level beyond that point, it will not go beyond that level
|
||||||
|
RULE_BOOL(Character, PerCharacterBucketMaxLevel, false) // This will check for data bucket 'CharMaxLevel', if player tries to level beyond that point, it will not go beyond that level
|
||||||
RULE_INT(Character, MaxExpLevel, 0) //Sets the Max Level attainable via Experience
|
RULE_INT(Character, MaxExpLevel, 0) //Sets the Max Level attainable via Experience
|
||||||
RULE_INT(Character, DeathExpLossLevel, 10) // Any level greater than this will lose exp on death
|
RULE_INT(Character, DeathExpLossLevel, 10) // Any level greater than this will lose exp on death
|
||||||
RULE_INT(Character, DeathExpLossMaxLevel, 255) // Any level greater than this will no longer lose exp on death
|
RULE_INT(Character, DeathExpLossMaxLevel, 255) // Any level greater than this will no longer lose exp on death
|
||||||
@ -342,7 +343,8 @@ RULE_INT(Spells, TranslocateTimeLimit, 0) // If not zero, time in seconds to acc
|
|||||||
RULE_INT(Spells, SacrificeMinLevel, 46) //first level Sacrifice will work on
|
RULE_INT(Spells, SacrificeMinLevel, 46) //first level Sacrifice will work on
|
||||||
RULE_INT(Spells, SacrificeMaxLevel, 69) //last level Sacrifice will work on
|
RULE_INT(Spells, SacrificeMaxLevel, 69) //last level Sacrifice will work on
|
||||||
RULE_INT(Spells, SacrificeItemID, 9963) //Item ID of the item Sacrifice will return (defaults to an EE)
|
RULE_INT(Spells, SacrificeItemID, 9963) //Item ID of the item Sacrifice will return (defaults to an EE)
|
||||||
RULE_BOOL(Spells, EnableSpellGlobals, false) // If Enabled, spells check the spell_globals table and compare character data from the quest globals before allowing that spell to scribe with scribespells
|
RULE_BOOL(Spells, EnableSpellGlobals, false) // If Enabled, spells check the spell_globals table and compare character data from their quest globals before allowing the spell to scribe with scribespells/traindiscs
|
||||||
|
RULE_BOOL(Spells, EnableSpellBuckets, false) // If Enabled, spells check the spell_buckets table and compare character data from their data buckets before allowing the spell to scribe with scribespells/traindiscs
|
||||||
RULE_INT(Spells, MaxBuffSlotsNPC, 60) // default to Tit's limit
|
RULE_INT(Spells, MaxBuffSlotsNPC, 60) // default to Tit's limit
|
||||||
RULE_INT(Spells, MaxSongSlotsNPC, 0) // NPCs don't have songs ...
|
RULE_INT(Spells, MaxSongSlotsNPC, 0) // NPCs don't have songs ...
|
||||||
RULE_INT(Spells, MaxDiscSlotsNPC, 0) // NPCs don't have discs ...
|
RULE_INT(Spells, MaxDiscSlotsNPC, 0) // NPCs don't have discs ...
|
||||||
@ -419,6 +421,7 @@ RULE_BOOL(Combat, EnableFearPathing, true)
|
|||||||
RULE_REAL(Combat, FleeMultiplier, 2.0) // Determines how quickly a NPC will slow down while fleeing. Decrease multiplier to slow NPC down quicker.
|
RULE_REAL(Combat, FleeMultiplier, 2.0) // Determines how quickly a NPC will slow down while fleeing. Decrease multiplier to slow NPC down quicker.
|
||||||
RULE_BOOL(Combat, FleeGray, true) // If true FleeGrayHPRatio will be used.
|
RULE_BOOL(Combat, FleeGray, true) // If true FleeGrayHPRatio will be used.
|
||||||
RULE_INT(Combat, FleeGrayHPRatio, 50) //HP % when a Gray NPC begins to flee.
|
RULE_INT(Combat, FleeGrayHPRatio, 50) //HP % when a Gray NPC begins to flee.
|
||||||
|
RULE_INT(Combat, FleeGrayMaxLevel, 18) // NPC's above this level won't do gray/green con flee
|
||||||
RULE_INT(Combat, FleeHPRatio, 25) //HP % when a NPC begins to flee.
|
RULE_INT(Combat, FleeHPRatio, 25) //HP % when a NPC begins to flee.
|
||||||
RULE_BOOL(Combat, FleeIfNotAlone, false) // If false, mobs won't flee if other mobs are in combat with it.
|
RULE_BOOL(Combat, FleeIfNotAlone, false) // If false, mobs won't flee if other mobs are in combat with it.
|
||||||
RULE_BOOL(Combat, AdjustProcPerMinute, true)
|
RULE_BOOL(Combat, AdjustProcPerMinute, true)
|
||||||
|
|||||||
@ -30,7 +30,7 @@
|
|||||||
Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
|
Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define CURRENT_BINARY_DATABASE_VERSION 9129
|
#define CURRENT_BINARY_DATABASE_VERSION 9131
|
||||||
#ifdef BOTS
|
#ifdef BOTS
|
||||||
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9021
|
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9021
|
||||||
#else
|
#else
|
||||||
|
|||||||
@ -116,17 +116,17 @@ public:
|
|||||||
inline void AccountTable(std::string t) { account_table = t; }
|
inline void AccountTable(std::string t) { account_table = t; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the value of local_network.
|
* Return the value of world account table.
|
||||||
*/
|
*/
|
||||||
inline std::string GetAccountTable() const { return account_table; }
|
inline std::string GetAccountTable() const { return account_table; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets world account table.
|
* Sets world registration table.
|
||||||
*/
|
*/
|
||||||
inline void WorldRegistrationTable(std::string t) { world_registration_table = t; }
|
inline void WorldRegistrationTable(std::string t) { world_registration_table = t; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the value of world account table.
|
* Return the value of world registration table.
|
||||||
*/
|
*/
|
||||||
inline std::string GetWorldRegistrationTable() const { return world_registration_table; }
|
inline std::string GetWorldRegistrationTable() const { return world_registration_table; }
|
||||||
|
|
||||||
@ -146,7 +146,7 @@ public:
|
|||||||
inline void WorldServerTypeTable(std::string t) { world_server_type_table = t; }
|
inline void WorldServerTypeTable(std::string t) { world_server_type_table = t; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the value of world admin account table.
|
* Return the value of world server type table.
|
||||||
*/
|
*/
|
||||||
inline std::string GetWorldServerTypeTable() const { return world_server_type_table; }
|
inline std::string GetWorldServerTypeTable() const { return world_server_type_table; }
|
||||||
|
|
||||||
|
|||||||
@ -381,8 +381,10 @@
|
|||||||
9125|2018_07_20_task_emote.sql|SHOW COLUMNS FROM `tasks` LIKE 'completion_emote'|empty|
|
9125|2018_07_20_task_emote.sql|SHOW COLUMNS FROM `tasks` LIKE 'completion_emote'|empty|
|
||||||
9126|2018_09_07_FastRegen.sql|SHOW COLUMNS FROM `zone` LIKE 'fast_regen_hp'|empty|
|
9126|2018_09_07_FastRegen.sql|SHOW COLUMNS FROM `zone` LIKE 'fast_regen_hp'|empty|
|
||||||
9127|2018_09_07_NPCMaxAggroDist.sql|SHOW COLUMNS FROM `zone` LIKE 'npc_max_aggro_dist'|empty|
|
9127|2018_09_07_NPCMaxAggroDist.sql|SHOW COLUMNS FROM `zone` LIKE 'npc_max_aggro_dist'|empty|
|
||||||
9128|2018_08_13_inventory_version_update.sql|SHOW TABLES LIKE 'inventory_versions'|empty|
|
9128|2018_08_13_inventory_version_update.sql|SHOW TABLES LIKE 'inventory_version'|not_empty|
|
||||||
9129|2018_08_13_inventory_update.sql|SELECT * FROM `inventory_versions` WHERE `version` = 2 and `step` = 0|not_empty|
|
9129|2018_08_13_inventory_update.sql|SHOW TABLES LIKE 'inventory_versions'|empty|
|
||||||
|
9130|2018_11_25_name_filter_update.sql|SHOW COLUMNS FROM `name_filter` LIKE 'id'|empty|
|
||||||
|
9131|2018_12_13_spell_buckets.sql|SHOW TABLES LIKE 'spell_buckets'|empty|
|
||||||
|
|
||||||
# Upgrade conditions:
|
# Upgrade conditions:
|
||||||
# This won't be needed after this system is implemented, but it is used database that are not
|
# This won't be needed after this system is implemented, but it is used database that are not
|
||||||
|
|||||||
@ -1,3 +1,66 @@
|
|||||||
|
DROP TABLE IF EXISTS `inventory_versions`;
|
||||||
|
DROP TABLE IF EXISTS `inventory_snapshots`;
|
||||||
|
|
||||||
|
|
||||||
|
CREATE TABLE `inventory_versions` (
|
||||||
|
`version` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||||
|
`step` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||||
|
`bot_step` INT(11) UNSIGNED NOT NULL DEFAULT '0'
|
||||||
|
)
|
||||||
|
COLLATE='latin1_swedish_ci'
|
||||||
|
ENGINE=MyISAM;
|
||||||
|
|
||||||
|
INSERT INTO `inventory_versions` VALUES (2, 0, 0);
|
||||||
|
|
||||||
|
|
||||||
|
CREATE TABLE `inventory_snapshots` (
|
||||||
|
`time_index` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||||
|
`charid` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||||
|
`slotid` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT '0',
|
||||||
|
`itemid` INT(11) UNSIGNED NULL DEFAULT '0',
|
||||||
|
`charges` SMALLINT(3) UNSIGNED NULL DEFAULT '0',
|
||||||
|
`color` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||||
|
`augslot1` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT '0',
|
||||||
|
`augslot2` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT '0',
|
||||||
|
`augslot3` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT '0',
|
||||||
|
`augslot4` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT '0',
|
||||||
|
`augslot5` MEDIUMINT(7) UNSIGNED NULL DEFAULT '0',
|
||||||
|
`augslot6` MEDIUMINT(7) NOT NULL DEFAULT '0',
|
||||||
|
`instnodrop` TINYINT(1) UNSIGNED NOT NULL DEFAULT '0',
|
||||||
|
`custom_data` TEXT NULL,
|
||||||
|
`ornamenticon` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||||
|
`ornamentidfile` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||||
|
`ornament_hero_model` INT(11) NOT NULL DEFAULT '0',
|
||||||
|
PRIMARY KEY (`time_index`, `charid`, `slotid`)
|
||||||
|
)
|
||||||
|
COLLATE='latin1_swedish_ci'
|
||||||
|
ENGINE=InnoDB;
|
||||||
|
|
||||||
|
|
||||||
|
CREATE TABLE `inventory_snapshots_v1_bak` (
|
||||||
|
`time_index` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||||
|
`charid` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||||
|
`slotid` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT '0',
|
||||||
|
`itemid` INT(11) UNSIGNED NULL DEFAULT '0',
|
||||||
|
`charges` SMALLINT(3) UNSIGNED NULL DEFAULT '0',
|
||||||
|
`color` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||||
|
`augslot1` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT '0',
|
||||||
|
`augslot2` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT '0',
|
||||||
|
`augslot3` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT '0',
|
||||||
|
`augslot4` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT '0',
|
||||||
|
`augslot5` MEDIUMINT(7) UNSIGNED NULL DEFAULT '0',
|
||||||
|
`augslot6` MEDIUMINT(7) NOT NULL DEFAULT '0',
|
||||||
|
`instnodrop` TINYINT(1) UNSIGNED NOT NULL DEFAULT '0',
|
||||||
|
`custom_data` TEXT NULL,
|
||||||
|
`ornamenticon` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||||
|
`ornamentidfile` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||||
|
`ornament_hero_model` INT(11) NOT NULL DEFAULT '0',
|
||||||
|
PRIMARY KEY (`time_index`, `charid`, `slotid`)
|
||||||
|
)
|
||||||
|
COLLATE='latin1_swedish_ci'
|
||||||
|
ENGINE=InnoDB;
|
||||||
|
|
||||||
|
|
||||||
-- create inventory v1 backup
|
-- create inventory v1 backup
|
||||||
SELECT @pre_timestamp := UNIX_TIMESTAMP(NOW());
|
SELECT @pre_timestamp := UNIX_TIMESTAMP(NOW());
|
||||||
INSERT INTO `inventory_snapshots_v1_bak`
|
INSERT INTO `inventory_snapshots_v1_bak`
|
||||||
|
|||||||
@ -1,61 +1 @@
|
|||||||
DROP TABLE IF EXISTS `inventory_version`;
|
DROP TABLE IF EXISTS `inventory_version`;
|
||||||
DROP TABLE IF EXISTS `inventory_snapshots`;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE TABLE `inventory_versions` (
|
|
||||||
`version` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
|
||||||
`step` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
|
||||||
`bot_step` INT(11) UNSIGNED NOT NULL DEFAULT '0'
|
|
||||||
)
|
|
||||||
COLLATE='latin1_swedish_ci'
|
|
||||||
ENGINE=MyISAM;
|
|
||||||
|
|
||||||
INSERT INTO `inventory_versions` VALUES (2, 0, 0);
|
|
||||||
|
|
||||||
|
|
||||||
CREATE TABLE `inventory_snapshots` (
|
|
||||||
`time_index` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
|
||||||
`charid` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
|
||||||
`slotid` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT '0',
|
|
||||||
`itemid` INT(11) UNSIGNED NULL DEFAULT '0',
|
|
||||||
`charges` SMALLINT(3) UNSIGNED NULL DEFAULT '0',
|
|
||||||
`color` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
|
||||||
`augslot1` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT '0',
|
|
||||||
`augslot2` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT '0',
|
|
||||||
`augslot3` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT '0',
|
|
||||||
`augslot4` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT '0',
|
|
||||||
`augslot5` MEDIUMINT(7) UNSIGNED NULL DEFAULT '0',
|
|
||||||
`augslot6` MEDIUMINT(7) NOT NULL DEFAULT '0',
|
|
||||||
`instnodrop` TINYINT(1) UNSIGNED NOT NULL DEFAULT '0',
|
|
||||||
`custom_data` TEXT NULL,
|
|
||||||
`ornamenticon` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
|
||||||
`ornamentidfile` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
|
||||||
`ornament_hero_model` INT(11) NOT NULL DEFAULT '0',
|
|
||||||
PRIMARY KEY (`time_index`, `charid`, `slotid`)
|
|
||||||
)
|
|
||||||
COLLATE='latin1_swedish_ci'
|
|
||||||
ENGINE=InnoDB;
|
|
||||||
|
|
||||||
|
|
||||||
CREATE TABLE `inventory_snapshots_v1_bak` (
|
|
||||||
`time_index` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
|
||||||
`charid` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
|
||||||
`slotid` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT '0',
|
|
||||||
`itemid` INT(11) UNSIGNED NULL DEFAULT '0',
|
|
||||||
`charges` SMALLINT(3) UNSIGNED NULL DEFAULT '0',
|
|
||||||
`color` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
|
||||||
`augslot1` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT '0',
|
|
||||||
`augslot2` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT '0',
|
|
||||||
`augslot3` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT '0',
|
|
||||||
`augslot4` MEDIUMINT(7) UNSIGNED NOT NULL DEFAULT '0',
|
|
||||||
`augslot5` MEDIUMINT(7) UNSIGNED NULL DEFAULT '0',
|
|
||||||
`augslot6` MEDIUMINT(7) NOT NULL DEFAULT '0',
|
|
||||||
`instnodrop` TINYINT(1) UNSIGNED NOT NULL DEFAULT '0',
|
|
||||||
`custom_data` TEXT NULL,
|
|
||||||
`ornamenticon` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
|
||||||
`ornamentidfile` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
|
||||||
`ornament_hero_model` INT(11) NOT NULL DEFAULT '0',
|
|
||||||
PRIMARY KEY (`time_index`, `charid`, `slotid`)
|
|
||||||
)
|
|
||||||
COLLATE='latin1_swedish_ci'
|
|
||||||
ENGINE=InnoDB;
|
|
||||||
|
|||||||
5
utils/sql/git/required/2018_11_25_name_filter_update.sql
Normal file
5
utils/sql/git/required/2018_11_25_name_filter_update.sql
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
ALTER TABLE `name_filter`
|
||||||
|
ADD COLUMN `id` INT(11) NULL AUTO_INCREMENT FIRST,
|
||||||
|
DROP PRIMARY KEY,
|
||||||
|
ADD PRIMARY KEY (`id`) USING BTREE,
|
||||||
|
ADD INDEX `name_search_index`(`name`);
|
||||||
10
utils/sql/git/required/2018_12_13_spell_buckets.sql
Normal file
10
utils/sql/git/required/2018_12_13_spell_buckets.sql
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
CREATE TABLE `spell_buckets` (
|
||||||
|
`spellid` bigint(11) unsigned NOT NULL,
|
||||||
|
`key` varchar(100) DEFAULT NULL,
|
||||||
|
`value` text,
|
||||||
|
PRIMARY KEY (`spellid`),
|
||||||
|
KEY `key_index` (`key`) USING BTREE
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
|
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Spells:EnableSpellBuckets', 'false', 'Enables spell buckets');
|
||||||
|
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Character:PerCharacterBucketMaxLevel', 'false', 'Enables data bucket-based max level.');
|
||||||
@ -10,6 +10,7 @@ adventure_template_entry
|
|||||||
adventure_template_entry_flavor
|
adventure_template_entry_flavor
|
||||||
altadv_vars
|
altadv_vars
|
||||||
alternate_currency
|
alternate_currency
|
||||||
|
auras
|
||||||
base_data
|
base_data
|
||||||
blocked_spells
|
blocked_spells
|
||||||
books
|
books
|
||||||
@ -59,6 +60,7 @@ merc_types
|
|||||||
merc_weaponinfo
|
merc_weaponinfo
|
||||||
merchantlist
|
merchantlist
|
||||||
mercs
|
mercs
|
||||||
|
name_filter
|
||||||
npc_emotes
|
npc_emotes
|
||||||
npc_faction
|
npc_faction
|
||||||
npc_faction_entries
|
npc_faction_entries
|
||||||
|
|||||||
@ -59,7 +59,6 @@ launcher_zones
|
|||||||
lfguild
|
lfguild
|
||||||
mail
|
mail
|
||||||
merchantlist_temp
|
merchantlist_temp
|
||||||
name_filter
|
|
||||||
object_contents
|
object_contents
|
||||||
petitions
|
petitions
|
||||||
player_titlesets
|
player_titlesets
|
||||||
@ -86,6 +85,7 @@ reports
|
|||||||
respawn_times
|
respawn_times
|
||||||
sharedbank
|
sharedbank
|
||||||
spell_globals
|
spell_globals
|
||||||
|
spell_buckets
|
||||||
timers
|
timers
|
||||||
trader
|
trader
|
||||||
trader_audit
|
trader_audit
|
||||||
|
|||||||
13
zone/aa.cpp
13
zone/aa.cpp
@ -1172,7 +1172,7 @@ void Client::ActivateAlternateAdvancementAbility(int rank_id, int target_id) {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
//check cooldown
|
//check cooldown
|
||||||
if(!p_timers.Expired(&database, rank->spell_type + pTimerAAStart)) {
|
if(!p_timers.Expired(&database, rank->spell_type + pTimerAAStart, false)) {
|
||||||
uint32 aaremain = p_timers.GetRemainingTime(rank->spell_type + pTimerAAStart);
|
uint32 aaremain = p_timers.GetRemainingTime(rank->spell_type + pTimerAAStart);
|
||||||
uint32 aaremain_hr = aaremain / (60 * 60);
|
uint32 aaremain_hr = aaremain / (60 * 60);
|
||||||
uint32 aaremain_min = (aaremain / 60) % 60;
|
uint32 aaremain_min = (aaremain / 60) % 60;
|
||||||
@ -1208,6 +1208,17 @@ void Client::ActivateAlternateAdvancementAbility(int rank_id, int target_id) {
|
|||||||
if (spells[rank->spell].targettype == ST_Pet || spells[rank->spell].targettype == ST_SummonedPet)
|
if (spells[rank->spell].targettype == ST_Pet || spells[rank->spell].targettype == ST_SummonedPet)
|
||||||
target_id = GetPetID();
|
target_id = GetPetID();
|
||||||
|
|
||||||
|
// extra handling for cast_not_standing spells
|
||||||
|
if (!spells[rank->spell].cast_not_standing) {
|
||||||
|
if (GetAppearance() == eaSitting) // we need to stand!
|
||||||
|
SetAppearance(eaStanding, false);
|
||||||
|
|
||||||
|
if (GetAppearance() != eaStanding) {
|
||||||
|
Message_StringID(MT_SpellFailure, STAND_TO_CAST);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Bards can cast instant cast AAs while they are casting another song
|
// Bards can cast instant cast AAs while they are casting another song
|
||||||
if(spells[rank->spell].cast_time == 0 && GetClass() == BARD && IsBardSong(casting_spell_id)) {
|
if(spells[rank->spell].cast_time == 0 && GetClass() == BARD && IsBardSong(casting_spell_id)) {
|
||||||
if(!SpellFinished(rank->spell, entity_list.GetMob(target_id), EQEmu::CastingSlot::AltAbility, spells[rank->spell].mana, -1, spells[rank->spell].ResistDiff, false)) {
|
if(!SpellFinished(rank->spell, entity_list.GetMob(target_id), EQEmu::CastingSlot::AltAbility, spells[rank->spell].mana, -1, spells[rank->spell].ResistDiff, false)) {
|
||||||
|
|||||||
@ -263,6 +263,16 @@ Client::Client(EQStreamInterface* ieqs)
|
|||||||
PendingSacrifice = false;
|
PendingSacrifice = false;
|
||||||
controlling_boat_id = 0;
|
controlling_boat_id = 0;
|
||||||
|
|
||||||
|
if (!RuleB(Character, PerCharacterQglobalMaxLevel) && !RuleB(Character, PerCharacterBucketMaxLevel)) {
|
||||||
|
SetClientMaxLevel(0);
|
||||||
|
} else if (RuleB(Character, PerCharacterQglobalMaxLevel)) {
|
||||||
|
int client_max_level = GetCharMaxLevelFromQGlobal();
|
||||||
|
SetClientMaxLevel(client_max_level);
|
||||||
|
} else if (RuleB(Character, PerCharacterBucketMaxLevel)) {
|
||||||
|
int client_max_level = GetCharMaxLevelFromBucket();
|
||||||
|
SetClientMaxLevel(client_max_level);
|
||||||
|
}
|
||||||
|
|
||||||
KarmaUpdateTimer = new Timer(RuleI(Chat, KarmaUpdateIntervalMS));
|
KarmaUpdateTimer = new Timer(RuleI(Chat, KarmaUpdateIntervalMS));
|
||||||
GlobalChatLimiterTimer = new Timer(RuleI(Chat, IntervalDurationMS));
|
GlobalChatLimiterTimer = new Timer(RuleI(Chat, IntervalDurationMS));
|
||||||
AttemptedMessages = 0;
|
AttemptedMessages = 0;
|
||||||
@ -1966,7 +1976,6 @@ void Client::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho)
|
|||||||
// ns->spawn.pvp = GetPVP(false) ? 1 : 0;
|
// ns->spawn.pvp = GetPVP(false) ? 1 : 0;
|
||||||
ns->spawn.show_name = true;
|
ns->spawn.show_name = true;
|
||||||
|
|
||||||
|
|
||||||
strcpy(ns->spawn.title, m_pp.title);
|
strcpy(ns->spawn.title, m_pp.title);
|
||||||
strcpy(ns->spawn.suffix, m_pp.suffix);
|
strcpy(ns->spawn.suffix, m_pp.suffix);
|
||||||
|
|
||||||
|
|||||||
@ -706,6 +706,8 @@ public:
|
|||||||
void SendGuildJoin(GuildJoin_Struct* gj);
|
void SendGuildJoin(GuildJoin_Struct* gj);
|
||||||
void RefreshGuildInfo();
|
void RefreshGuildInfo();
|
||||||
|
|
||||||
|
int GetClientMaxLevel() const { return client_max_level; }
|
||||||
|
void SetClientMaxLevel(int max_level) { client_max_level = max_level; }
|
||||||
|
|
||||||
void CheckManaEndUpdate();
|
void CheckManaEndUpdate();
|
||||||
void SendManaUpdate();
|
void SendManaUpdate();
|
||||||
@ -782,8 +784,10 @@ public:
|
|||||||
void UnscribeSpellAll(bool update_client = true);
|
void UnscribeSpellAll(bool update_client = true);
|
||||||
void UntrainDisc(int slot, bool update_client = true);
|
void UntrainDisc(int slot, bool update_client = true);
|
||||||
void UntrainDiscAll(bool update_client = true);
|
void UntrainDiscAll(bool update_client = true);
|
||||||
bool SpellGlobalCheck(uint16 Spell_ID, uint32 Char_ID);
|
bool SpellGlobalCheck(uint16 spell_id, uint32 char_id);
|
||||||
|
bool SpellBucketCheck(uint16 spell_id, uint32 char_id);
|
||||||
uint32 GetCharMaxLevelFromQGlobal();
|
uint32 GetCharMaxLevelFromQGlobal();
|
||||||
|
uint32 GetCharMaxLevelFromBucket();
|
||||||
|
|
||||||
inline bool IsSitting() const {return (playeraction == 1);}
|
inline bool IsSitting() const {return (playeraction == 1);}
|
||||||
inline bool IsBecomeNPC() const { return npcflag; }
|
inline bool IsBecomeNPC() const { return npcflag; }
|
||||||
@ -1663,6 +1667,8 @@ private:
|
|||||||
void InterrogateInventory_(bool errorcheck, Client* requester, int16 head, int16 index, const EQEmu::ItemInstance* inst, const EQEmu::ItemInstance* parent, bool log, bool silent, bool &error, int depth);
|
void InterrogateInventory_(bool errorcheck, Client* requester, int16 head, int16 index, const EQEmu::ItemInstance* inst, const EQEmu::ItemInstance* parent, bool log, bool silent, bool &error, int depth);
|
||||||
bool InterrogateInventory_error(int16 head, int16 index, const EQEmu::ItemInstance* inst, const EQEmu::ItemInstance* parent, int depth);
|
bool InterrogateInventory_error(int16 head, int16 index, const EQEmu::ItemInstance* inst, const EQEmu::ItemInstance* parent, int depth);
|
||||||
|
|
||||||
|
int client_max_level;
|
||||||
|
|
||||||
#ifdef BOTS
|
#ifdef BOTS
|
||||||
struct BotOwnerOptions {
|
struct BotOwnerOptions {
|
||||||
bool death_marquee;
|
bool death_marquee;
|
||||||
|
|||||||
@ -1420,6 +1420,15 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
|
|||||||
drakkin_tattoo = m_pp.drakkin_tattoo;
|
drakkin_tattoo = m_pp.drakkin_tattoo;
|
||||||
drakkin_details = m_pp.drakkin_details;
|
drakkin_details = m_pp.drakkin_details;
|
||||||
|
|
||||||
|
// Max Level for Character:PerCharacterQglobalMaxLevel and Character:PerCharacterBucketMaxLevel
|
||||||
|
int client_max_level = 0;
|
||||||
|
if (RuleB(Character, PerCharacterQglobalMaxLevel)) {
|
||||||
|
client_max_level = GetCharMaxLevelFromQGlobal();
|
||||||
|
} else if (RuleB(Character, PerCharacterBucketMaxLevel)) {
|
||||||
|
client_max_level = GetCharMaxLevelFromBucket();
|
||||||
|
}
|
||||||
|
SetClientMaxLevel(client_max_level);
|
||||||
|
|
||||||
// we know our class now, so we might have to fix our consume timer!
|
// we know our class now, so we might have to fix our consume timer!
|
||||||
if (class_ == MONK)
|
if (class_ == MONK)
|
||||||
consume_food_timer.SetTimer(CONSUMPTION_MNK_TIMER);
|
consume_food_timer.SetTimer(CONSUMPTION_MNK_TIMER);
|
||||||
|
|||||||
2
zone/command.cpp
Normal file → Executable file
2
zone/command.cpp
Normal file → Executable file
@ -1688,7 +1688,7 @@ void command_zheader(Client *c, const Seperator *sep)
|
|||||||
c->Message(0, "Invalid Zone Name: %s", sep->argplus[1]);
|
c->Message(0, "Invalid Zone Name: %s", sep->argplus[1]);
|
||||||
else {
|
else {
|
||||||
|
|
||||||
if (zone->LoadZoneCFG(sep->argplus[1], true))
|
if (zone->LoadZoneCFG(sep->argplus[1], 0))
|
||||||
c->Message(0, "Successfully loaded zone header for %s from database.", sep->argplus[1]);
|
c->Message(0, "Successfully loaded zone header for %s from database.", sep->argplus[1]);
|
||||||
else
|
else
|
||||||
c->Message(0, "Failed to load zone header %s from database", sep->argplus[1]);
|
c->Message(0, "Failed to load zone header %s from database", sep->argplus[1]);
|
||||||
|
|||||||
@ -2887,6 +2887,20 @@ XS(XS__GetInstanceID) {
|
|||||||
XSRETURN_UV(id);
|
XSRETURN_UV(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XS(XS__GetInstanceIDByCharID);
|
||||||
|
XS(XS__GetInstanceIDByCharID) {
|
||||||
|
dXSARGS;
|
||||||
|
if (items != 3)
|
||||||
|
Perl_croak(aTHX_ "Usage: quest::GetInstanceIDByCharID(string zone_name, uint16 version, uint32 char_id)");
|
||||||
|
|
||||||
|
char *zone = (char *) SvPV_nolen(ST(0));
|
||||||
|
uint16 version = (int) SvUV(ST(1));
|
||||||
|
uint32 char_id = (int) SvUV(ST(2));
|
||||||
|
uint16 id = quest_manager.GetInstanceIDByCharID(zone, version, char_id);
|
||||||
|
|
||||||
|
XSRETURN_UV(id);
|
||||||
|
}
|
||||||
|
|
||||||
XS(XS__GetCharactersInInstance);
|
XS(XS__GetCharactersInInstance);
|
||||||
XS(XS__GetCharactersInInstance) {
|
XS(XS__GetCharactersInInstance) {
|
||||||
dXSARGS;
|
dXSARGS;
|
||||||
@ -2938,6 +2952,19 @@ XS(XS__AssignToInstance) {
|
|||||||
XSRETURN_EMPTY;
|
XSRETURN_EMPTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XS(XS__AssignToInstanceByCharID);
|
||||||
|
XS(XS__AssignToInstanceByCharID) {
|
||||||
|
dXSARGS;
|
||||||
|
if (items != 2)
|
||||||
|
Perl_croak(aTHX_ "Usage: quest::AssignToInstanceByCharID(uint16 instance_id, uint32 char_id)");
|
||||||
|
|
||||||
|
uint16 instance_id = (int) SvUV(ST(0));
|
||||||
|
uint32 char_id = (int) SvUV(ST(1));
|
||||||
|
quest_manager.AssignToInstanceByCharID(instance_id, char_id);
|
||||||
|
|
||||||
|
XSRETURN_EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
XS(XS__AssignGroupToInstance);
|
XS(XS__AssignGroupToInstance);
|
||||||
XS(XS__AssignGroupToInstance) {
|
XS(XS__AssignGroupToInstance) {
|
||||||
dXSARGS;
|
dXSARGS;
|
||||||
@ -2974,6 +3001,19 @@ XS(XS__RemoveFromInstance) {
|
|||||||
XSRETURN_EMPTY;
|
XSRETURN_EMPTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XS(XS__RemoveFromInstanceByCharID);
|
||||||
|
XS(XS__RemoveFromInstanceByCharID) {
|
||||||
|
dXSARGS;
|
||||||
|
if (items != 2)
|
||||||
|
Perl_croak(aTHX_ "Usage: quest::RemoveFromInstanceByCharID(uint16 instance_id, uint32 char_id)");
|
||||||
|
|
||||||
|
uint16 instance_id = (int) SvUV(ST(0));
|
||||||
|
uint32 char_id = (int) SvUV(ST(1));
|
||||||
|
quest_manager.RemoveFromInstanceByCharID(instance_id, char_id);
|
||||||
|
|
||||||
|
XSRETURN_EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
XS(XS__RemoveAllFromInstance);
|
XS(XS__RemoveAllFromInstance);
|
||||||
XS(XS__RemoveAllFromInstance) {
|
XS(XS__RemoveAllFromInstance) {
|
||||||
dXSARGS;
|
dXSARGS;
|
||||||
@ -3692,6 +3732,7 @@ EXTERN_C XS(boot_quest) {
|
|||||||
newXS(strcpy(buf, "AssignGroupToInstance"), XS__AssignGroupToInstance, file);
|
newXS(strcpy(buf, "AssignGroupToInstance"), XS__AssignGroupToInstance, file);
|
||||||
newXS(strcpy(buf, "AssignRaidToInstance"), XS__AssignRaidToInstance, file);
|
newXS(strcpy(buf, "AssignRaidToInstance"), XS__AssignRaidToInstance, file);
|
||||||
newXS(strcpy(buf, "AssignToInstance"), XS__AssignToInstance, file);
|
newXS(strcpy(buf, "AssignToInstance"), XS__AssignToInstance, file);
|
||||||
|
newXS(strcpy(buf, "AssignToInstanceByCharID"), XS__AssignToInstanceByCharID, file);
|
||||||
newXS(strcpy(buf, "ChooseRandom"), XS__ChooseRandom, file);
|
newXS(strcpy(buf, "ChooseRandom"), XS__ChooseRandom, file);
|
||||||
newXS(strcpy(buf, "CreateInstance"), XS__CreateInstance, file);
|
newXS(strcpy(buf, "CreateInstance"), XS__CreateInstance, file);
|
||||||
newXS(strcpy(buf, "DestroyInstance"), XS__DestroyInstance, file);
|
newXS(strcpy(buf, "DestroyInstance"), XS__DestroyInstance, file);
|
||||||
@ -3703,12 +3744,14 @@ EXTERN_C XS(boot_quest) {
|
|||||||
newXS(strcpy(buf, "FlyMode"), XS__FlyMode, file);
|
newXS(strcpy(buf, "FlyMode"), XS__FlyMode, file);
|
||||||
newXS(strcpy(buf, "GetCharactersInInstance"), XS__GetCharactersInInstance, file);
|
newXS(strcpy(buf, "GetCharactersInInstance"), XS__GetCharactersInInstance, file);
|
||||||
newXS(strcpy(buf, "GetInstanceID"), XS__GetInstanceID, file);
|
newXS(strcpy(buf, "GetInstanceID"), XS__GetInstanceID, file);
|
||||||
|
newXS(strcpy(buf, "GetInstanceIDByCharID"), XS__GetInstanceIDByCharID, file);
|
||||||
newXS(strcpy(buf, "GetSpellResistType"), XS__GetSpellResistType, file);
|
newXS(strcpy(buf, "GetSpellResistType"), XS__GetSpellResistType, file);
|
||||||
newXS(strcpy(buf, "GetSpellTargetType"), XS__GetSpellTargetType, file);
|
newXS(strcpy(buf, "GetSpellTargetType"), XS__GetSpellTargetType, file);
|
||||||
newXS(strcpy(buf, "GetTimeSeconds"), XS__GetTimeSeconds, file);
|
newXS(strcpy(buf, "GetTimeSeconds"), XS__GetTimeSeconds, file);
|
||||||
newXS(strcpy(buf, "GetZoneID"), XS__GetZoneID, file);
|
newXS(strcpy(buf, "GetZoneID"), XS__GetZoneID, file);
|
||||||
newXS(strcpy(buf, "GetZoneLongName"), XS__GetZoneLongName, file);
|
newXS(strcpy(buf, "GetZoneLongName"), XS__GetZoneLongName, file);
|
||||||
newXS(strcpy(buf, "get_data"), XS__get_data, file);
|
newXS(strcpy(buf, "get_data"), XS__get_data, file);
|
||||||
|
newXS(strcpy(buf, "get_data_expires"), XS__get_data_expires, file);
|
||||||
newXS(strcpy(buf, "set_data"), XS__set_data, file);
|
newXS(strcpy(buf, "set_data"), XS__set_data, file);
|
||||||
newXS(strcpy(buf, "delete_data"), XS__delete_data, file);
|
newXS(strcpy(buf, "delete_data"), XS__delete_data, file);
|
||||||
newXS(strcpy(buf, "IsBeneficialSpell"), XS__IsBeneficialSpell, file);
|
newXS(strcpy(buf, "IsBeneficialSpell"), XS__IsBeneficialSpell, file);
|
||||||
@ -3720,6 +3763,7 @@ EXTERN_C XS(boot_quest) {
|
|||||||
newXS(strcpy(buf, "MovePCInstance"), XS__MovePCInstance, file);
|
newXS(strcpy(buf, "MovePCInstance"), XS__MovePCInstance, file);
|
||||||
newXS(strcpy(buf, "RemoveAllFromInstance"), XS__RemoveAllFromInstance, file);
|
newXS(strcpy(buf, "RemoveAllFromInstance"), XS__RemoveAllFromInstance, file);
|
||||||
newXS(strcpy(buf, "RemoveFromInstance"), XS__RemoveFromInstance, file);
|
newXS(strcpy(buf, "RemoveFromInstance"), XS__RemoveFromInstance, file);
|
||||||
|
newXS(strcpy(buf, "RemoveFromInstanceByCharID"), XS__RemoveFromInstanceByCharID, file);
|
||||||
newXS(strcpy(buf, "SendMail"), XS__SendMail, file);
|
newXS(strcpy(buf, "SendMail"), XS__SendMail, file);
|
||||||
newXS(strcpy(buf, "SetRunning"), XS__SetRunning, file);
|
newXS(strcpy(buf, "SetRunning"), XS__SetRunning, file);
|
||||||
newXS(strcpy(buf, "activespeakactivity"), XS__activespeakactivity, file);
|
newXS(strcpy(buf, "activespeakactivity"), XS__activespeakactivity, file);
|
||||||
|
|||||||
32
zone/exp.cpp
32
zone/exp.cpp
@ -684,14 +684,12 @@ void Client::SetEXP(uint32 set_exp, uint32 set_aaxp, bool isrezzexp) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(RuleB(Character, PerCharacterQglobalMaxLevel)){
|
if (GetClientMaxLevel() > 0) {
|
||||||
uint32 MaxLevel = GetCharMaxLevelFromQGlobal();
|
int client_max_level = GetClientMaxLevel();
|
||||||
if(MaxLevel){
|
if (GetLevel() >= client_max_level) {
|
||||||
if(GetLevel() >= MaxLevel){
|
uint32 expneeded = GetEXPForLevel(client_max_level);
|
||||||
uint32 expneeded = GetEXPForLevel(MaxLevel);
|
if(set_exp > expneeded) {
|
||||||
if(set_exp > expneeded) {
|
set_exp = expneeded;
|
||||||
set_exp = expneeded;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1130,7 +1128,23 @@ uint32 Client::GetCharMaxLevelFromQGlobal() {
|
|||||||
++gcount;
|
++gcount;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 Client::GetCharMaxLevelFromBucket() {
|
||||||
|
uint32 char_id = this->CharacterID();
|
||||||
|
std::string query = StringFormat("SELECT value FROM data_buckets WHERE key = '%i-CharMaxLevel'", char_id);
|
||||||
|
auto results = database.QueryDatabase(query);
|
||||||
|
if (!results.Success()) {
|
||||||
|
Log(Logs::General, Logs::Error, "Data bucket for CharMaxLevel for char ID %i failed.", char_id);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (results.RowCount() > 0) {
|
||||||
|
auto row = results.begin();
|
||||||
|
return atoi(row[0]);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 Client::GetRequiredAAExperience() {
|
uint32 Client::GetRequiredAAExperience() {
|
||||||
|
|||||||
@ -62,7 +62,7 @@ void Mob::CheckFlee() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If no special flee_percent check for Gray or Other con rates
|
// If no special flee_percent check for Gray or Other con rates
|
||||||
if(GetLevelCon(hate_top->GetLevel(), GetLevel()) == CON_GRAY && fleeratio == 0 && RuleB(Combat, FleeGray)) {
|
if(GetLevelCon(hate_top->GetLevel(), GetLevel()) == CON_GRAY && fleeratio == 0 && RuleB(Combat, FleeGray) && GetLevel() <= RuleI(Combat, FleeGrayMaxLevel)) {
|
||||||
fleeratio = RuleI(Combat, FleeGrayHPRatio);
|
fleeratio = RuleI(Combat, FleeGrayHPRatio);
|
||||||
} else if(fleeratio == 0) {
|
} else if(fleeratio == 0) {
|
||||||
fleeratio = RuleI(Combat, FleeHPRatio );
|
fleeratio = RuleI(Combat, FleeHPRatio );
|
||||||
|
|||||||
@ -892,10 +892,18 @@ int lua_get_instance_id(const char *zone, uint32 version) {
|
|||||||
return quest_manager.GetInstanceID(zone, version);
|
return quest_manager.GetInstanceID(zone, version);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int lua_get_instance_id_by_char_id(const char *zone, uint32 version, uint32 char_id) {
|
||||||
|
return quest_manager.GetInstanceIDByCharID(zone, version, char_id);
|
||||||
|
}
|
||||||
|
|
||||||
void lua_assign_to_instance(uint32 instance_id) {
|
void lua_assign_to_instance(uint32 instance_id) {
|
||||||
quest_manager.AssignToInstance(instance_id);
|
quest_manager.AssignToInstance(instance_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void lua_assign_to_instance_by_char_id(uint32 instance_id, uint32 char_id) {
|
||||||
|
quest_manager.AssignToInstanceByCharID(instance_id, char_id);
|
||||||
|
}
|
||||||
|
|
||||||
void lua_assign_group_to_instance(uint32 instance_id) {
|
void lua_assign_group_to_instance(uint32 instance_id) {
|
||||||
quest_manager.AssignGroupToInstance(instance_id);
|
quest_manager.AssignGroupToInstance(instance_id);
|
||||||
}
|
}
|
||||||
@ -908,6 +916,10 @@ void lua_remove_from_instance(uint32 instance_id) {
|
|||||||
quest_manager.RemoveFromInstance(instance_id);
|
quest_manager.RemoveFromInstance(instance_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void lua_remove_from_instance_by_char_id(uint32 instance_id, uint32 char_id) {
|
||||||
|
quest_manager.RemoveFromInstanceByCharID(instance_id, char_id);
|
||||||
|
}
|
||||||
|
|
||||||
void lua_remove_all_from_instance(uint32 instance_id) {
|
void lua_remove_all_from_instance(uint32 instance_id) {
|
||||||
quest_manager.RemoveAllFromInstance(instance_id);
|
quest_manager.RemoveAllFromInstance(instance_id);
|
||||||
}
|
}
|
||||||
@ -1707,6 +1719,7 @@ luabind::scope lua_register_general() {
|
|||||||
luabind::def("say_link", (std::string(*)(const char*,bool))&lua_say_link),
|
luabind::def("say_link", (std::string(*)(const char*,bool))&lua_say_link),
|
||||||
luabind::def("say_link", (std::string(*)(const char*))&lua_say_link),
|
luabind::def("say_link", (std::string(*)(const char*))&lua_say_link),
|
||||||
luabind::def("get_data", (std::string(*)(std::string))&lua_get_data),
|
luabind::def("get_data", (std::string(*)(std::string))&lua_get_data),
|
||||||
|
luabind::def("get_data_expires", (std::string(*)(std::string))&lua_get_data_expires),
|
||||||
luabind::def("set_data", (void(*)(std::string, std::string))&lua_set_data),
|
luabind::def("set_data", (void(*)(std::string, std::string))&lua_set_data),
|
||||||
luabind::def("set_data", (void(*)(std::string, std::string, std::string))&lua_set_data),
|
luabind::def("set_data", (void(*)(std::string, std::string, std::string))&lua_set_data),
|
||||||
luabind::def("delete_data", (bool(*)(std::string))&lua_delete_data),
|
luabind::def("delete_data", (bool(*)(std::string))&lua_delete_data),
|
||||||
@ -1715,13 +1728,16 @@ luabind::scope lua_register_general() {
|
|||||||
luabind::def("destroy_instance", &lua_destroy_instance),
|
luabind::def("destroy_instance", &lua_destroy_instance),
|
||||||
luabind::def("update_instance_timer", &lua_update_instance_timer),
|
luabind::def("update_instance_timer", &lua_update_instance_timer),
|
||||||
luabind::def("get_instance_id", &lua_get_instance_id),
|
luabind::def("get_instance_id", &lua_get_instance_id),
|
||||||
|
luabind::def("get_instance_id_by_char_id", &lua_get_instance_id_by_char_id),
|
||||||
luabind::def("get_instance_timer", &lua_get_instance_timer),
|
luabind::def("get_instance_timer", &lua_get_instance_timer),
|
||||||
luabind::def("get_instance_timer_by_id", &lua_get_instance_timer_by_id),
|
luabind::def("get_instance_timer_by_id", &lua_get_instance_timer_by_id),
|
||||||
luabind::def("get_characters_in_instance", &lua_get_characters_in_instance),
|
luabind::def("get_characters_in_instance", &lua_get_characters_in_instance),
|
||||||
luabind::def("assign_to_instance", &lua_assign_to_instance),
|
luabind::def("assign_to_instance", &lua_assign_to_instance),
|
||||||
|
luabind::def("assign_to_instance_by_char_id", &lua_assign_to_instance_by_char_id),
|
||||||
luabind::def("assign_group_to_instance", &lua_assign_group_to_instance),
|
luabind::def("assign_group_to_instance", &lua_assign_group_to_instance),
|
||||||
luabind::def("assign_raid_to_instance", &lua_assign_raid_to_instance),
|
luabind::def("assign_raid_to_instance", &lua_assign_raid_to_instance),
|
||||||
luabind::def("remove_from_instance", &lua_remove_from_instance),
|
luabind::def("remove_from_instance", &lua_remove_from_instance),
|
||||||
|
luabind::def("remove_from_instance_by_char_id", &lua_remove_from_instance_by_char_id),
|
||||||
luabind::def("remove_all_from_instance", &lua_remove_all_from_instance),
|
luabind::def("remove_all_from_instance", &lua_remove_all_from_instance),
|
||||||
luabind::def("flag_instance_by_group_leader", &lua_flag_instance_by_group_leader),
|
luabind::def("flag_instance_by_group_leader", &lua_flag_instance_by_group_leader),
|
||||||
luabind::def("flag_instance_by_raid_leader", &lua_flag_instance_by_raid_leader),
|
luabind::def("flag_instance_by_raid_leader", &lua_flag_instance_by_raid_leader),
|
||||||
|
|||||||
@ -333,6 +333,36 @@ void Lua_NPC::AI_SetRoambox(float dist, float max_x, float min_x, float max_y, f
|
|||||||
self->AI_SetRoambox(dist, max_x, min_x, max_y, min_y, delay, mindelay);
|
self->AI_SetRoambox(dist, max_x, min_x, max_y, min_y, delay, mindelay);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Lua_NPC::SetFollowID(int id) {
|
||||||
|
Lua_Safe_Call_Void();
|
||||||
|
self->SetFollowID(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Lua_NPC::SetFollowDistance(int dist) {
|
||||||
|
Lua_Safe_Call_Void();
|
||||||
|
self->SetFollowDistance(dist);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Lua_NPC::SetFollowCanRun(bool v) {
|
||||||
|
Lua_Safe_Call_Void();
|
||||||
|
self->SetFollowCanRun(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Lua_NPC::GetFollowID() {
|
||||||
|
Lua_Safe_Call_Int();
|
||||||
|
return self->GetFollowID();
|
||||||
|
}
|
||||||
|
|
||||||
|
int Lua_NPC::GetFollowDistance() {
|
||||||
|
Lua_Safe_Call_Int();
|
||||||
|
return self->GetFollowDistance();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Lua_NPC::GetFollowCanRun() {
|
||||||
|
Lua_Safe_Call_Bool();
|
||||||
|
return self->GetFollowCanRun();
|
||||||
|
}
|
||||||
|
|
||||||
int Lua_NPC::GetNPCSpellsID() {
|
int Lua_NPC::GetNPCSpellsID() {
|
||||||
Lua_Safe_Call_Int();
|
Lua_Safe_Call_Int();
|
||||||
return self->GetNPCSpellsID();
|
return self->GetNPCSpellsID();
|
||||||
@ -572,6 +602,13 @@ luabind::scope lua_register_npc() {
|
|||||||
.def("IsGuarding", (bool(Lua_NPC::*)(void))&Lua_NPC::IsGuarding)
|
.def("IsGuarding", (bool(Lua_NPC::*)(void))&Lua_NPC::IsGuarding)
|
||||||
.def("AI_SetRoambox", (void(Lua_NPC::*)(float,float,float,float,float))&Lua_NPC::AI_SetRoambox)
|
.def("AI_SetRoambox", (void(Lua_NPC::*)(float,float,float,float,float))&Lua_NPC::AI_SetRoambox)
|
||||||
.def("AI_SetRoambox", (void(Lua_NPC::*)(float,float,float,float,float,uint32,uint32))&Lua_NPC::AI_SetRoambox)
|
.def("AI_SetRoambox", (void(Lua_NPC::*)(float,float,float,float,float,uint32,uint32))&Lua_NPC::AI_SetRoambox)
|
||||||
|
.def("SetFollowID", (void(Lua_NPC::*)(int))&Lua_NPC::SetFollowID)
|
||||||
|
.def("SetFollowDistance", (void(Lua_NPC::*)(int))&Lua_NPC::SetFollowDistance)
|
||||||
|
.def("SetFollowCanRun", (void(Lua_NPC::*)(bool))&Lua_NPC::SetFollowCanRun)
|
||||||
|
.def("GetFollowID", (int(Lua_NPC::*)(void))&Lua_NPC::GetFollowID)
|
||||||
|
.def("GetFollowDistance", (int(Lua_NPC::*)(void))&Lua_NPC::GetFollowDistance)
|
||||||
|
.def("GetFollowCanRun", (bool(Lua_NPC::*)(void))&Lua_NPC::GetFollowCanRun)
|
||||||
|
.def("GetNPCSpellsID", (int(Lua_NPC::*)(void))&Lua_NPC::GetNPCSpellsID)
|
||||||
.def("GetNPCSpellsID", (int(Lua_NPC::*)(void))&Lua_NPC::GetNPCSpellsID)
|
.def("GetNPCSpellsID", (int(Lua_NPC::*)(void))&Lua_NPC::GetNPCSpellsID)
|
||||||
.def("GetSpawnPointID", (int(Lua_NPC::*)(void))&Lua_NPC::GetSpawnPointID)
|
.def("GetSpawnPointID", (int(Lua_NPC::*)(void))&Lua_NPC::GetSpawnPointID)
|
||||||
.def("GetSpawnPointX", (float(Lua_NPC::*)(void))&Lua_NPC::GetSpawnPointX)
|
.def("GetSpawnPointX", (float(Lua_NPC::*)(void))&Lua_NPC::GetSpawnPointX)
|
||||||
|
|||||||
@ -92,6 +92,12 @@ public:
|
|||||||
bool IsGuarding();
|
bool IsGuarding();
|
||||||
void AI_SetRoambox(float dist, float max_x, float min_x, float max_y, float min_y);
|
void AI_SetRoambox(float dist, float max_x, float min_x, float max_y, float min_y);
|
||||||
void AI_SetRoambox(float dist, float max_x, float min_x, float max_y, float min_y, uint32 delay, uint32 mindelay);
|
void AI_SetRoambox(float dist, float max_x, float min_x, float max_y, float min_y, uint32 delay, uint32 mindelay);
|
||||||
|
void SetFollowID(int id);
|
||||||
|
void SetFollowDistance(int dist);
|
||||||
|
void SetFollowCanRun(bool v);
|
||||||
|
int GetFollowID();
|
||||||
|
int GetFollowDistance();
|
||||||
|
bool GetFollowCanRun();
|
||||||
int GetNPCSpellsID();
|
int GetNPCSpellsID();
|
||||||
int GetSpawnPointID();
|
int GetSpawnPointID();
|
||||||
float GetSpawnPointX();
|
float GetSpawnPointX();
|
||||||
|
|||||||
@ -383,8 +383,9 @@ Mob::Mob(const char* in_name,
|
|||||||
m_CurrentWayPoint = glm::vec4();
|
m_CurrentWayPoint = glm::vec4();
|
||||||
cur_wp_pause = 0;
|
cur_wp_pause = 0;
|
||||||
patrol = 0;
|
patrol = 0;
|
||||||
follow = 0;
|
follow_id = 0;
|
||||||
follow_dist = 100; // Default Distance for Follow
|
follow_dist = 100; // Default Distance for Follow
|
||||||
|
follow_run = true; // We can run if distance great enough
|
||||||
no_target_hotkey = false;
|
no_target_hotkey = false;
|
||||||
flee_mode = false;
|
flee_mode = false;
|
||||||
currently_fleeing = false;
|
currently_fleeing = false;
|
||||||
|
|||||||
@ -695,10 +695,12 @@ public:
|
|||||||
virtual bool IsAttackAllowed(Mob *target, bool isSpellAttack = false);
|
virtual bool IsAttackAllowed(Mob *target, bool isSpellAttack = false);
|
||||||
bool IsTargeted() const { return (targeted > 0); }
|
bool IsTargeted() const { return (targeted > 0); }
|
||||||
inline void IsTargeted(int in_tar) { targeted += in_tar; if(targeted < 0) targeted = 0;}
|
inline void IsTargeted(int in_tar) { targeted += in_tar; if(targeted < 0) targeted = 0;}
|
||||||
void SetFollowID(uint32 id) { follow = id; }
|
void SetFollowID(uint32 id) { follow_id = id; }
|
||||||
void SetFollowDistance(uint32 dist) { follow_dist = dist; }
|
void SetFollowDistance(uint32 dist) { follow_dist = dist; }
|
||||||
uint32 GetFollowID() const { return follow; }
|
void SetFollowCanRun(bool v) { follow_run = v; }
|
||||||
|
uint32 GetFollowID() const { return follow_id; }
|
||||||
uint32 GetFollowDistance() const { return follow_dist; }
|
uint32 GetFollowDistance() const { return follow_dist; }
|
||||||
|
bool GetFollowCanRun() const { return follow_run; }
|
||||||
inline bool IsRareSpawn() const { return rare_spawn; }
|
inline bool IsRareSpawn() const { return rare_spawn; }
|
||||||
inline void SetRareSpawn(bool in) { rare_spawn = in; }
|
inline void SetRareSpawn(bool in) { rare_spawn = in; }
|
||||||
|
|
||||||
@ -1235,8 +1237,9 @@ protected:
|
|||||||
uint16 ownerid;
|
uint16 ownerid;
|
||||||
PetType typeofpet;
|
PetType typeofpet;
|
||||||
int16 petpower;
|
int16 petpower;
|
||||||
uint32 follow;
|
uint32 follow_id;
|
||||||
uint32 follow_dist;
|
uint32 follow_dist;
|
||||||
|
bool follow_run;
|
||||||
bool no_target_hotkey;
|
bool no_target_hotkey;
|
||||||
bool rare_spawn;
|
bool rare_spawn;
|
||||||
|
|
||||||
|
|||||||
@ -1635,6 +1635,8 @@ void Mob::AI_Process() {
|
|||||||
Mob *follow = entity_list.GetMob(static_cast<uint16>(GetFollowID()));
|
Mob *follow = entity_list.GetMob(static_cast<uint16>(GetFollowID()));
|
||||||
if (!follow) {
|
if (!follow) {
|
||||||
SetFollowID(0);
|
SetFollowID(0);
|
||||||
|
SetFollowDistance(100);
|
||||||
|
SetFollowCanRun(true);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
@ -1647,7 +1649,8 @@ void Mob::AI_Process() {
|
|||||||
if (distance >= follow_distance) {
|
if (distance >= follow_distance) {
|
||||||
int speed = GetWalkspeed();
|
int speed = GetWalkspeed();
|
||||||
|
|
||||||
if (distance >= follow_distance + 150) {
|
// maybe we want the NPC to only walk doing follow logic
|
||||||
|
if (GetFollowCanRun() && distance >= follow_distance + 150) {
|
||||||
speed = GetRunspeed();
|
speed = GetRunspeed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
11
zone/npc.cpp
11
zone/npc.cpp
@ -2632,7 +2632,16 @@ FACTION_VALUE NPC::CheckNPCFactionAlly(int32 other_faction) {
|
|||||||
return FACTION_INDIFFERENT;
|
return FACTION_INDIFFERENT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return FACTION_INDIFFERENT;
|
|
||||||
|
// I believe that the assumption is, barring no entry in npc_faction_entries
|
||||||
|
// that two npcs on like faction con ally to each other. This catches cases
|
||||||
|
// where an npc is on a faction but has no hits (hence no entry in
|
||||||
|
// npc_faction_entries).
|
||||||
|
|
||||||
|
if (GetPrimaryFaction() == other_faction)
|
||||||
|
return FACTION_ALLY;
|
||||||
|
else
|
||||||
|
return FACTION_INDIFFERENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NPC::IsFactionListAlly(uint32 other_faction) {
|
bool NPC::IsFactionListAlly(uint32 other_faction) {
|
||||||
|
|||||||
@ -976,37 +976,44 @@ void QuestManager::permagender(int gender_id) {
|
|||||||
uint16 QuestManager::scribespells(uint8 max_level, uint8 min_level) {
|
uint16 QuestManager::scribespells(uint8 max_level, uint8 min_level) {
|
||||||
QuestManagerCurrentQuestVars();
|
QuestManagerCurrentQuestVars();
|
||||||
uint16 book_slot, count;
|
uint16 book_slot, count;
|
||||||
uint16 curspell;
|
uint16 spell_id;
|
||||||
|
|
||||||
uint32 Char_ID = initiator->CharacterID();
|
uint32 char_id = initiator->CharacterID();
|
||||||
bool SpellGlobalRule = RuleB(Spells, EnableSpellGlobals);
|
bool SpellGlobalRule = RuleB(Spells, EnableSpellGlobals);
|
||||||
|
bool SpellBucketRule = RuleB(Spells, EnableSpellBuckets);
|
||||||
bool SpellGlobalCheckResult = 0;
|
bool SpellGlobalCheckResult = 0;
|
||||||
|
bool SpellBucketCheckResult = 0;
|
||||||
|
|
||||||
|
|
||||||
for(curspell = 0, book_slot = initiator->GetNextAvailableSpellBookSlot(), count = 0; curspell < SPDAT_RECORDS && book_slot < MAX_PP_SPELLBOOK; curspell++, book_slot = initiator->GetNextAvailableSpellBookSlot(book_slot))
|
for(spell_id = 0, book_slot = initiator->GetNextAvailableSpellBookSlot(), count = 0; spell_id < SPDAT_RECORDS && book_slot < MAX_PP_SPELLBOOK; spell_id++, book_slot = initiator->GetNextAvailableSpellBookSlot(book_slot))
|
||||||
{
|
{
|
||||||
if
|
if
|
||||||
(
|
(
|
||||||
spells[curspell].classes[WARRIOR] != 0 && //check if spell exists
|
spells[spell_id].classes[WARRIOR] != 0 && //check if spell exists
|
||||||
spells[curspell].classes[initiator->GetPP().class_-1] <= max_level && //maximum level
|
spells[spell_id].classes[initiator->GetPP().class_-1] <= max_level && //maximum level
|
||||||
spells[curspell].classes[initiator->GetPP().class_-1] >= min_level && //minimum level
|
spells[spell_id].classes[initiator->GetPP().class_-1] >= min_level && //minimum level
|
||||||
spells[curspell].skill != 52 &&
|
spells[spell_id].skill != 52 &&
|
||||||
spells[curspell].effectid[EFFECT_COUNT - 1] != 10
|
spells[spell_id].effectid[EFFECT_COUNT - 1] != 10
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (book_slot == -1) //no more book slots
|
if (book_slot == -1) //no more book slots
|
||||||
break;
|
break;
|
||||||
if(!IsDiscipline(curspell) && !initiator->HasSpellScribed(curspell)) { //isn't a discipline & we don't already have it scribed
|
if(!IsDiscipline(spell_id) && !initiator->HasSpellScribed(spell_id)) { //isn't a discipline & we don't already have it scribed
|
||||||
if (SpellGlobalRule) {
|
if (SpellGlobalRule) {
|
||||||
// Bool to see if the character has the required QGlobal to scribe it if one exists in the Spell_Globals table
|
// Bool to see if the character has the required QGlobal to scribe it if one exists in the Spell_Globals table
|
||||||
SpellGlobalCheckResult = initiator->SpellGlobalCheck(curspell, Char_ID);
|
SpellGlobalCheckResult = initiator->SpellGlobalCheck(spell_id, char_id);
|
||||||
if (SpellGlobalCheckResult) {
|
if (SpellGlobalCheckResult) {
|
||||||
initiator->ScribeSpell(curspell, book_slot);
|
initiator->ScribeSpell(spell_id, book_slot);
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
}
|
} else if (SpellBucketRule) {
|
||||||
else {
|
SpellBucketCheckResult = initiator->SpellBucketCheck(spell_id, char_id);
|
||||||
initiator->ScribeSpell(curspell, book_slot);
|
if (SpellBucketCheckResult) {
|
||||||
|
initiator->ScribeSpell(spell_id, book_slot);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
initiator->ScribeSpell(spell_id, book_slot);
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1018,46 +1025,59 @@ uint16 QuestManager::scribespells(uint8 max_level, uint8 min_level) {
|
|||||||
uint16 QuestManager::traindiscs(uint8 max_level, uint8 min_level) {
|
uint16 QuestManager::traindiscs(uint8 max_level, uint8 min_level) {
|
||||||
QuestManagerCurrentQuestVars();
|
QuestManagerCurrentQuestVars();
|
||||||
uint16 count;
|
uint16 count;
|
||||||
uint16 curspell;
|
uint16 spell_id;
|
||||||
|
|
||||||
uint32 Char_ID = initiator->CharacterID();
|
uint32 char_id = initiator->CharacterID();
|
||||||
bool SpellGlobalRule = RuleB(Spells, EnableSpellGlobals);
|
bool SpellGlobalRule = RuleB(Spells, EnableSpellGlobals);
|
||||||
|
bool SpellBucketRule = RuleB(Spells, EnableSpellBuckets);
|
||||||
bool SpellGlobalCheckResult = 0;
|
bool SpellGlobalCheckResult = 0;
|
||||||
|
bool SpellBucketCheckResult = 0;
|
||||||
|
|
||||||
for(curspell = 0, count = 0; curspell < SPDAT_RECORDS; curspell++)
|
for(spell_id = 0, count = 0; spell_id < SPDAT_RECORDS; spell_id++)
|
||||||
{
|
{
|
||||||
if
|
if
|
||||||
(
|
(
|
||||||
spells[curspell].classes[WARRIOR] != 0 && //check if spell exists
|
spells[spell_id].classes[WARRIOR] != 0 && //check if spell exists
|
||||||
spells[curspell].classes[initiator->GetPP().class_-1] <= max_level && //maximum level
|
spells[spell_id].classes[initiator->GetPP().class_-1] <= max_level && //maximum level
|
||||||
spells[curspell].classes[initiator->GetPP().class_-1] >= min_level && //minimum level
|
spells[spell_id].classes[initiator->GetPP().class_-1] >= min_level && //minimum level
|
||||||
spells[curspell].skill != 52 &&
|
spells[spell_id].skill != 52 &&
|
||||||
( !RuleB(Spells, UseCHAScribeHack) || spells[curspell].effectid[EFFECT_COUNT - 1] != 10 )
|
( !RuleB(Spells, UseCHAScribeHack) || spells[spell_id].effectid[EFFECT_COUNT - 1] != 10 )
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if(IsDiscipline(curspell)){
|
if(IsDiscipline(spell_id)){
|
||||||
//we may want to come up with a function like Client::GetNextAvailableSpellBookSlot() to help speed this up a little
|
//we may want to come up with a function like Client::GetNextAvailableSpellBookSlot() to help speed this up a little
|
||||||
for(uint32 r = 0; r < MAX_PP_DISCIPLINES; r++) {
|
for(uint32 r = 0; r < MAX_PP_DISCIPLINES; r++) {
|
||||||
if(initiator->GetPP().disciplines.values[r] == curspell) {
|
if(initiator->GetPP().disciplines.values[r] == spell_id) {
|
||||||
initiator->Message(13, "You already know this discipline.");
|
initiator->Message(13, "You already know this discipline.");
|
||||||
break; //continue the 1st loop
|
break; //continue the 1st loop
|
||||||
}
|
}
|
||||||
else if(initiator->GetPP().disciplines.values[r] == 0) {
|
else if(initiator->GetPP().disciplines.values[r] == 0) {
|
||||||
if (SpellGlobalRule) {
|
if (SpellGlobalRule) {
|
||||||
// Bool to see if the character has the required QGlobal to train it if one exists in the Spell_Globals table
|
// Bool to see if the character has the required QGlobal to train it if one exists in the Spell_Globals table
|
||||||
SpellGlobalCheckResult = initiator->SpellGlobalCheck(curspell, Char_ID);
|
SpellGlobalCheckResult = initiator->SpellGlobalCheck(spell_id, char_id);
|
||||||
if (SpellGlobalCheckResult) {
|
if (SpellGlobalCheckResult) {
|
||||||
initiator->GetPP().disciplines.values[r] = curspell;
|
initiator->GetPP().disciplines.values[r] = spell_id;
|
||||||
database.SaveCharacterDisc(Char_ID, r, curspell);
|
database.SaveCharacterDisc(char_id, r, spell_id);
|
||||||
initiator->SendDisciplineUpdate();
|
initiator->SendDisciplineUpdate();
|
||||||
initiator->Message(0, "You have learned a new discipline!");
|
initiator->Message(0, "You have learned a new discipline!");
|
||||||
count++; //success counter
|
count++; //success counter
|
||||||
}
|
}
|
||||||
break; //continue the 1st loop
|
break; //continue the 1st loop
|
||||||
|
} else if (SpellBucketRule) {
|
||||||
|
// Bool to see if the character has the required bucket to train it if one exists in the spell_buckets table
|
||||||
|
SpellBucketCheckResult = initiator->SpellBucketCheck(spell_id, char_id);
|
||||||
|
if (SpellBucketCheckResult) {
|
||||||
|
initiator->GetPP().disciplines.values[r] = spell_id;
|
||||||
|
database.SaveCharacterDisc(char_id, r, spell_id);
|
||||||
|
initiator->SendDisciplineUpdate();
|
||||||
|
initiator->Message(0, "You have learned a new discipline!");
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
initiator->GetPP().disciplines.values[r] = curspell;
|
initiator->GetPP().disciplines.values[r] = spell_id;
|
||||||
database.SaveCharacterDisc(Char_ID, r, curspell);
|
database.SaveCharacterDisc(char_id, r, spell_id);
|
||||||
initiator->SendDisciplineUpdate();
|
initiator->SendDisciplineUpdate();
|
||||||
initiator->Message(0, "You have learned a new discipline!");
|
initiator->Message(0, "You have learned a new discipline!");
|
||||||
count++; //success counter
|
count++; //success counter
|
||||||
@ -2661,6 +2681,10 @@ uint16 QuestManager::GetInstanceID(const char *zone, int16 version)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16 QuestManager::GetInstanceIDByCharID(const char *zone, int16 version, uint32 char_id) {
|
||||||
|
return database.GetInstanceID(zone, char_id, version);
|
||||||
|
}
|
||||||
|
|
||||||
void QuestManager::AssignToInstance(uint16 instance_id)
|
void QuestManager::AssignToInstance(uint16 instance_id)
|
||||||
{
|
{
|
||||||
QuestManagerCurrentQuestVars();
|
QuestManagerCurrentQuestVars();
|
||||||
@ -2670,6 +2694,10 @@ void QuestManager::AssignToInstance(uint16 instance_id)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QuestManager::AssignToInstanceByCharID(uint16 instance_id, uint32 char_id) {
|
||||||
|
database.AddClientToInstance(instance_id, char_id);
|
||||||
|
}
|
||||||
|
|
||||||
void QuestManager::AssignGroupToInstance(uint16 instance_id)
|
void QuestManager::AssignGroupToInstance(uint16 instance_id)
|
||||||
{
|
{
|
||||||
QuestManagerCurrentQuestVars();
|
QuestManagerCurrentQuestVars();
|
||||||
@ -2710,6 +2738,10 @@ void QuestManager::RemoveFromInstance(uint16 instance_id)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QuestManager::RemoveFromInstanceByCharID(uint16 instance_id, uint32 char_id) {
|
||||||
|
database.RemoveClientFromInstance(instance_id, char_id);
|
||||||
|
}
|
||||||
|
|
||||||
void QuestManager::RemoveAllFromInstance(uint16 instance_id)
|
void QuestManager::RemoveAllFromInstance(uint16 instance_id)
|
||||||
{
|
{
|
||||||
QuestManagerCurrentQuestVars();
|
QuestManagerCurrentQuestVars();
|
||||||
|
|||||||
@ -234,10 +234,13 @@ public:
|
|||||||
uint32 GetInstanceTimerByID(uint16 instance_id = 0);
|
uint32 GetInstanceTimerByID(uint16 instance_id = 0);
|
||||||
void DestroyInstance(uint16 instance_id);
|
void DestroyInstance(uint16 instance_id);
|
||||||
uint16 GetInstanceID(const char *zone, int16 version);
|
uint16 GetInstanceID(const char *zone, int16 version);
|
||||||
|
uint16 GetInstanceIDByCharID(const char *zone, int16 version, uint32 char_id);
|
||||||
void AssignToInstance(uint16 instance_id);
|
void AssignToInstance(uint16 instance_id);
|
||||||
|
void AssignToInstanceByCharID(uint16 instance_id, uint32 char_id);
|
||||||
void AssignGroupToInstance(uint16 instance_id);
|
void AssignGroupToInstance(uint16 instance_id);
|
||||||
void AssignRaidToInstance(uint16 instance_id);
|
void AssignRaidToInstance(uint16 instance_id);
|
||||||
void RemoveFromInstance(uint16 instance_id);
|
void RemoveFromInstance(uint16 instance_id);
|
||||||
|
void RemoveFromInstanceByCharID(uint16 instance_id, uint32 char_id);
|
||||||
//void RemoveGroupFromInstance(uint16 instance_id); //potentially useful but not implmented at this time.
|
//void RemoveGroupFromInstance(uint16 instance_id); //potentially useful but not implmented at this time.
|
||||||
//void RemoveRaidFromInstance(uint16 instance_id); //potentially useful but not implmented at this time.
|
//void RemoveRaidFromInstance(uint16 instance_id); //potentially useful but not implmented at this time.
|
||||||
void RemoveAllFromInstance(uint16 instance_id);
|
void RemoveAllFromInstance(uint16 instance_id);
|
||||||
|
|||||||
@ -5154,14 +5154,11 @@ int Client::FindSpellBookSlotBySpellID(uint16 spellid) {
|
|||||||
return -1; //default
|
return -1; //default
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Client::SpellGlobalCheck(uint16 spell_ID, uint32 char_ID) {
|
bool Client::SpellGlobalCheck(uint16 spell_id, uint32 char_id) {
|
||||||
|
std::string spell_global_name;
|
||||||
std::string spell_Global_Name;
|
int spell_global_value;
|
||||||
int spell_Global_Value;
|
int global_value;
|
||||||
int global_Value;
|
std::string query = StringFormat("SELECT qglobal, value FROM spell_globals WHERE spellid = %i", spell_id);
|
||||||
|
|
||||||
std::string query = StringFormat("SELECT qglobal, value FROM spell_globals "
|
|
||||||
"WHERE spellid = %i", spell_ID);
|
|
||||||
auto results = database.QueryDatabase(query);
|
auto results = database.QueryDatabase(query);
|
||||||
if (!results.Success()) {
|
if (!results.Success()) {
|
||||||
return false; // Query failed, so prevent spell from scribing just in case
|
return false; // Query failed, so prevent spell from scribing just in case
|
||||||
@ -5171,37 +5168,79 @@ bool Client::SpellGlobalCheck(uint16 spell_ID, uint32 char_ID) {
|
|||||||
return true; // Spell ID isn't listed in the spells_global table, so it is not restricted from scribing
|
return true; // Spell ID isn't listed in the spells_global table, so it is not restricted from scribing
|
||||||
|
|
||||||
auto row = results.begin();
|
auto row = results.begin();
|
||||||
spell_Global_Name = row[0];
|
spell_global_name = row[0];
|
||||||
spell_Global_Value = atoi(row[1]);
|
spell_global_value = atoi(row[1]);
|
||||||
|
|
||||||
if (spell_Global_Name.empty())
|
if (spell_global_name.empty())
|
||||||
return true; // If the entry in the spell_globals table has nothing set for the qglobal name
|
return true; // If the entry in the spell_globals table has nothing set for the qglobal name
|
||||||
|
|
||||||
query = StringFormat("SELECT value FROM quest_globals "
|
query = StringFormat("SELECT value FROM quest_globals "
|
||||||
"WHERE charid = %i AND name = '%s'",
|
"WHERE charid = %i AND name = '%s'",
|
||||||
char_ID, spell_Global_Name.c_str());
|
char_id, spell_global_name.c_str());
|
||||||
results = database.QueryDatabase(query);
|
results = database.QueryDatabase(query);
|
||||||
if (!results.Success()) {
|
if (!results.Success()) {
|
||||||
Log(Logs::General, Logs::Error, "Spell ID %i query of spell_globals with Name: '%s' Value: '%i' failed", spell_ID, spell_Global_Name.c_str(), spell_Global_Value);
|
Log(Logs::General, Logs::Error, "Spell ID %i query of spell_globals with Name: '%s' Value: '%i' failed", spell_id, spell_global_name.c_str(), spell_global_value);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (results.RowCount() != 1) {
|
if (results.RowCount() != 1) {
|
||||||
Log(Logs::General, Logs::Error, "Char ID: %i does not have the Qglobal Name: '%s' for Spell ID %i", char_ID, spell_Global_Name.c_str(), spell_ID);
|
Log(Logs::General, Logs::Error, "Char ID: %i does not have the Qglobal Name: '%s' for Spell ID %i", char_id, spell_global_name.c_str(), spell_id);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
row = results.begin();
|
||||||
|
global_value = atoi(row[0]);
|
||||||
|
if (global_value == spell_global_value)
|
||||||
|
return true; // If the values match from both tables, allow the spell to be scribed
|
||||||
|
else if (global_value > spell_global_value)
|
||||||
|
return true; // Check if the qglobal value is greater than the require spellglobal value
|
||||||
|
|
||||||
|
// If no matching result found in qglobals, don't scribe this spell
|
||||||
|
Log(Logs::General, Logs::Error, "Char ID: %i Spell_globals Name: '%s' Value: '%i' did not match QGlobal Value: '%i' for Spell ID %i", char_id, spell_global_name.c_str(), spell_global_value, global_value, spell_id);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Client::SpellBucketCheck(uint16 spell_id, uint32 char_id) {
|
||||||
|
std::string spell_bucket_name;
|
||||||
|
int spell_bucket_value;
|
||||||
|
int bucket_value;
|
||||||
|
std::string query = StringFormat("SELECT key, value FROM spell_buckets WHERE spellid = %i", spell_id);
|
||||||
|
auto results = database.QueryDatabase(query);
|
||||||
|
if (!results.Success())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (results.RowCount() != 1)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
auto row = results.begin();
|
||||||
|
spell_bucket_name = row[0];
|
||||||
|
spell_bucket_value = atoi(row[1]);
|
||||||
|
if (spell_bucket_name.empty())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
query = StringFormat("SELECT value FROM data_buckets WHERE key = '%i-%s'", char_id, spell_bucket_name.c_str());
|
||||||
|
results = database.QueryDatabase(query);
|
||||||
|
if (!results.Success()) {
|
||||||
|
Log(Logs::General, Logs::Error, "Spell bucket %s for spell ID %i for char ID %i failed.", spell_bucket_name.c_str(), spell_id, char_id);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (results.RowCount() != 1) {
|
||||||
|
Log(Logs::General, Logs::Error, "Spell bucket %s does not exist for spell ID %i for char ID %i.", spell_bucket_name.c_str(), spell_id, char_id);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
row = results.begin();
|
row = results.begin();
|
||||||
|
|
||||||
global_Value = atoi(row[0]);
|
bucket_value = atoi(row[0]);
|
||||||
|
|
||||||
if (global_Value == spell_Global_Value)
|
if (bucket_value == spell_bucket_value)
|
||||||
return true; // If the values match from both tables, allow the spell to be scribed
|
return true; // If the values match from both tables, allow the spell to be scribed
|
||||||
else if (global_Value > spell_Global_Value)
|
else if (bucket_value > spell_bucket_value)
|
||||||
return true; // Check if the qglobal value is greater than the require spellglobal value
|
return true; // Check if the data bucket value is greater than the required spell bucket value
|
||||||
|
|
||||||
// If no matching result found in qglobals, don't scribe this spell
|
// If no matching result found in spell buckets, don't scribe this spell
|
||||||
Log(Logs::General, Logs::Error, "Char ID: %i Spell_globals Name: '%s' Value: '%i' did not match QGlobal Value: '%i' for Spell ID %i", char_ID, spell_Global_Name.c_str(), spell_Global_Value, global_Value, spell_ID);
|
Log(Logs::General, Logs::Error, "Spell bucket %s for spell ID %i for char ID %i did not match value %i.", spell_bucket_name.c_str(), spell_id, char_id, spell_bucket_value);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -428,6 +428,7 @@
|
|||||||
#define NO_LONGER_HIDDEN 12337 //You are no longer hidden.
|
#define NO_LONGER_HIDDEN 12337 //You are no longer hidden.
|
||||||
#define STOP_SNEAKING 12338 //You stop sneaking
|
#define STOP_SNEAKING 12338 //You stop sneaking
|
||||||
#define NOT_IN_CONTROL 12368 //You do not have control of yourself right now.
|
#define NOT_IN_CONTROL 12368 //You do not have control of yourself right now.
|
||||||
|
#define STAND_TO_CAST 12441 //You must be standing to cast a spell.
|
||||||
#define ALREADY_CASTING 12442 //You are already casting a spell!
|
#define ALREADY_CASTING 12442 //You are already casting a spell!
|
||||||
#define SHIMMERS_BRIEFLY 12444 //Your %1 shimmers briefly.
|
#define SHIMMERS_BRIEFLY 12444 //Your %1 shimmers briefly.
|
||||||
#define SENSE_CORPSE_NOT_NAME 12446 //You don't sense any corpses of that name.
|
#define SENSE_CORPSE_NOT_NAME 12446 //You don't sense any corpses of that name.
|
||||||
|
|||||||
@ -1295,7 +1295,7 @@ EQEmu::ItemInstance* Client::FindTraderItemBySerialNumber(int32 SerialNumber){
|
|||||||
GetItems_Struct* Client::GetTraderItems(){
|
GetItems_Struct* Client::GetTraderItems(){
|
||||||
|
|
||||||
const EQEmu::ItemInstance* item = nullptr;
|
const EQEmu::ItemInstance* item = nullptr;
|
||||||
uint16 SlotID = 0;
|
uint16 SlotID = INVALID_INDEX;
|
||||||
|
|
||||||
auto gis = new GetItems_Struct;
|
auto gis = new GetItems_Struct;
|
||||||
|
|
||||||
@ -1304,9 +1304,14 @@ GetItems_Struct* Client::GetTraderItems(){
|
|||||||
uint8 ndx = 0;
|
uint8 ndx = 0;
|
||||||
|
|
||||||
for (int i = EQEmu::invslot::GENERAL_BEGIN; i <= EQEmu::invslot::GENERAL_END; i++) {
|
for (int i = EQEmu::invslot::GENERAL_BEGIN; i <= EQEmu::invslot::GENERAL_END; i++) {
|
||||||
|
if (ndx >= 80)
|
||||||
|
break;
|
||||||
item = this->GetInv().GetItem(i);
|
item = this->GetInv().GetItem(i);
|
||||||
if(item && item->GetItem()->ID == 17899){ //Traders Satchel
|
if(item && item->GetItem()->ID == 17899){ //Traders Satchel
|
||||||
for (int x = EQEmu::invbag::SLOT_BEGIN; x <= EQEmu::invbag::SLOT_END; x++) {
|
for (int x = EQEmu::invbag::SLOT_BEGIN; x <= EQEmu::invbag::SLOT_END; x++) {
|
||||||
|
if (ndx >= 80)
|
||||||
|
break;
|
||||||
|
|
||||||
SlotID = EQEmu::InventoryProfile::CalcSlotId(i, x);
|
SlotID = EQEmu::InventoryProfile::CalcSlotId(i, x);
|
||||||
|
|
||||||
item = this->GetInv().GetItem(SlotID);
|
item = this->GetInv().GetItem(SlotID);
|
||||||
|
|||||||
65
zone/zone.cpp
Normal file → Executable file
65
zone/zone.cpp
Normal file → Executable file
@ -893,7 +893,7 @@ bool Zone::Init(bool iStaticZone) {
|
|||||||
SetStaticZone(iStaticZone);
|
SetStaticZone(iStaticZone);
|
||||||
|
|
||||||
//load the zone config file.
|
//load the zone config file.
|
||||||
if (!LoadZoneCFG(zone->GetShortName(), zone->GetInstanceVersion(), true)) // try loading the zone name...
|
if (!LoadZoneCFG(zone->GetShortName(), zone->GetInstanceVersion())) // try loading the zone name...
|
||||||
LoadZoneCFG(zone->GetFileName(), zone->GetInstanceVersion()); // if that fails, try the file name, then load defaults
|
LoadZoneCFG(zone->GetFileName(), zone->GetInstanceVersion()); // if that fails, try the file name, then load defaults
|
||||||
|
|
||||||
if(RuleManager::Instance()->GetActiveRulesetID() != default_ruleset)
|
if(RuleManager::Instance()->GetActiveRulesetID() != default_ruleset)
|
||||||
@ -1054,39 +1054,31 @@ void Zone::ReloadStaticData() {
|
|||||||
zone->LoadNPCEmotes(&NPCEmoteList);
|
zone->LoadNPCEmotes(&NPCEmoteList);
|
||||||
|
|
||||||
//load the zone config file.
|
//load the zone config file.
|
||||||
if (!LoadZoneCFG(zone->GetShortName(), zone->GetInstanceVersion(), true)) // try loading the zone name...
|
if (!LoadZoneCFG(zone->GetShortName(), zone->GetInstanceVersion())) // try loading the zone name...
|
||||||
LoadZoneCFG(zone->GetFileName(), zone->GetInstanceVersion()); // if that fails, try the file name, then load defaults
|
LoadZoneCFG(zone->GetFileName(), zone->GetInstanceVersion()); // if that fails, try the file name, then load defaults
|
||||||
|
|
||||||
Log(Logs::General, Logs::Status, "Zone Static Data Reloaded.");
|
Log(Logs::General, Logs::Status, "Zone Static Data Reloaded.");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Zone::LoadZoneCFG(const char* filename, uint16 instance_id, bool DontLoadDefault)
|
bool Zone::LoadZoneCFG(const char* filename, uint16 instance_id)
|
||||||
{
|
{
|
||||||
|
|
||||||
memset(&newzone_data, 0, sizeof(NewZone_Struct));
|
memset(&newzone_data, 0, sizeof(NewZone_Struct));
|
||||||
if(instance_id == 0)
|
map_name = nullptr;
|
||||||
|
|
||||||
|
if(!database.GetZoneCFG(database.GetZoneID(filename), instance_id, &newzone_data, can_bind,
|
||||||
|
can_combat, can_levitate, can_castoutdoor, is_city, is_hotzone, allow_mercs, zone_type, default_ruleset, &map_name))
|
||||||
{
|
{
|
||||||
map_name = nullptr;
|
// If loading a non-zero instance failed, try loading the default
|
||||||
if(!database.GetZoneCFG(database.GetZoneID(filename), 0, &newzone_data, can_bind,
|
if (instance_id != 0)
|
||||||
can_combat, can_levitate, can_castoutdoor, is_city, is_hotzone, allow_mercs, zone_type, default_ruleset, &map_name))
|
|
||||||
{
|
|
||||||
Log(Logs::General, Logs::Error, "Error loading the Zone Config.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//Fall back to base zone if we don't find the instance version.
|
|
||||||
map_name = nullptr;
|
|
||||||
if(!database.GetZoneCFG(database.GetZoneID(filename), instance_id, &newzone_data, can_bind,
|
|
||||||
can_combat, can_levitate, can_castoutdoor, is_city, is_hotzone, allow_mercs, zone_type, default_ruleset, &map_name))
|
|
||||||
{
|
{
|
||||||
safe_delete_array(map_name);
|
safe_delete_array(map_name);
|
||||||
if(!database.GetZoneCFG(database.GetZoneID(filename), 0, &newzone_data, can_bind,
|
if(!database.GetZoneCFG(database.GetZoneID(filename), 0, &newzone_data, can_bind, can_combat, can_levitate,
|
||||||
can_combat, can_levitate, can_castoutdoor, is_city, is_hotzone, allow_mercs, zone_type, default_ruleset, &map_name))
|
can_castoutdoor, is_city, is_hotzone, allow_mercs, zone_type, default_ruleset, &map_name))
|
||||||
{
|
{
|
||||||
Log(Logs::General, Logs::Error, "Error loading the Zone Config.");
|
Log(Logs::General, Logs::Error, "Error loading the Zone Config.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1274,7 +1266,8 @@ bool Zone::Process() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Weather_Timer->Check()){
|
if(Weather_Timer->Check())
|
||||||
|
{
|
||||||
Weather_Timer->Disable();
|
Weather_Timer->Disable();
|
||||||
this->ChangeWeather();
|
this->ChangeWeather();
|
||||||
}
|
}
|
||||||
@ -1860,26 +1853,22 @@ bool Zone::RemoveSpawnGroup(uint32 in_id) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ZoneDatabase::GetDecayTimes(npcDecayTimes_Struct *npcCorpseDecayTimes)
|
||||||
// Added By Hogie
|
{
|
||||||
bool ZoneDatabase::GetDecayTimes(npcDecayTimes_Struct* npcCorpseDecayTimes) {
|
const std::string query =
|
||||||
|
"SELECT varname, value FROM variables WHERE varname LIKE 'decaytime%%' ORDER BY varname";
|
||||||
const std::string query = "SELECT varname, value FROM variables WHERE varname LIKE 'decaytime%%' ORDER BY varname";
|
|
||||||
auto results = QueryDatabase(query);
|
auto results = QueryDatabase(query);
|
||||||
if (!results.Success())
|
if (!results.Success())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (auto row = results.begin(); row != results.end(); ++row, ++index) {
|
for (auto row = results.begin(); row != results.end(); ++row, ++index) {
|
||||||
Seperator sep(row[0]);
|
Seperator sep(row[0]);
|
||||||
npcCorpseDecayTimes[index].minlvl = atoi(sep.arg[1]);
|
npcCorpseDecayTimes[index].minlvl = atoi(sep.arg[1]);
|
||||||
npcCorpseDecayTimes[index].maxlvl = atoi(sep.arg[2]);
|
npcCorpseDecayTimes[index].maxlvl = atoi(sep.arg[2]);
|
||||||
|
|
||||||
if (atoi(row[1]) > 7200)
|
npcCorpseDecayTimes[index].seconds = std::min(24 * 60 * 60, atoi(row[1]));
|
||||||
npcCorpseDecayTimes[index].seconds = 720;
|
}
|
||||||
else
|
|
||||||
npcCorpseDecayTimes[index].seconds = atoi(row[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
2
zone/zone.h
Normal file → Executable file
2
zone/zone.h
Normal file → Executable file
@ -93,7 +93,7 @@ public:
|
|||||||
bool is_zone_time_localized;
|
bool is_zone_time_localized;
|
||||||
|
|
||||||
bool Init(bool iStaticZone);
|
bool Init(bool iStaticZone);
|
||||||
bool LoadZoneCFG(const char* filename, uint16 instance_id, bool DontLoadDefault = false);
|
bool LoadZoneCFG(const char* filename, uint16 instance_id);
|
||||||
bool SaveZoneCFG();
|
bool SaveZoneCFG();
|
||||||
bool IsLoaded();
|
bool IsLoaded();
|
||||||
bool IsPVPZone() { return pvpzone; }
|
bool IsPVPZone() { return pvpzone; }
|
||||||
|
|||||||
@ -4356,15 +4356,15 @@ uint32 ZoneDatabase::GetCharacterCorpseCount(uint32 char_id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32 ZoneDatabase::GetCharacterCorpseID(uint32 char_id, uint8 corpse) {
|
uint32 ZoneDatabase::GetCharacterCorpseID(uint32 char_id, uint8 corpse) {
|
||||||
std::string query = StringFormat("SELECT `id` FROM `character_corpses` WHERE `charid` = '%u'", char_id);
|
std::string query = StringFormat("SELECT `id` FROM `character_corpses` WHERE `charid` = '%u' limit %d, 1", char_id, corpse);
|
||||||
auto results = QueryDatabase(query);
|
|
||||||
|
|
||||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
auto results = QueryDatabase(query);
|
||||||
for (int i = 0; i < corpse; i++) {
|
auto row = results.begin();
|
||||||
return atoul(row[0]);
|
|
||||||
}
|
if (row != results.end())
|
||||||
}
|
return atoul(row[0]);
|
||||||
return 0;
|
else
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 ZoneDatabase::GetCharacterCorpseItemCount(uint32 corpse_id){
|
uint32 ZoneDatabase::GetCharacterCorpseItemCount(uint32 corpse_id){
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user