mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-24 21:31:28 +00:00
Merge branch 'master' into lets_move
This commit is contained in:
commit
909cbd8b97
@ -1,5 +1,28 @@
|
||||
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
||||
-------------------------------------------------------
|
||||
== 12/29/2015 ==
|
||||
Akkadius: Implemented standardized zone controller scripts (Rule Zone, UseZoneController) Defaulted to true
|
||||
- When a zone boots, it will spawn an invisible npc by the name of zone_controller
|
||||
- Lua and Perl scripts can be represented with this npc as zone_controller.pl/lua
|
||||
- This NPC's ID is ruled be define ZONE_CONTROLLER_NPC_ID 10
|
||||
- Two EVENT's uniquely are handled with this NPC/controller (They only work with the zone_controller NPC)
|
||||
- EVENT_SPAWN_ZONE :: All NPC spawns in the zone trigger the controller and pass the following variables:
|
||||
$spawned_entity_id
|
||||
$spawned_npc_id
|
||||
- EVENT_DEATH_ZONE :: All NPC deaths in the zone trigger the controller event and pass the following variables:
|
||||
$killer_id
|
||||
$killer_damage
|
||||
$killer_spell
|
||||
$killer_skill
|
||||
$killed_npc_id
|
||||
|
||||
== 12/28/2015 ==
|
||||
Kinglykrab: Added GetInstanceTimer() to Perl and Lua.
|
||||
- Added GetInstanceTimerByID(instance_id) to Perl and Lua.
|
||||
- Note: If you do not provide an instance id in the method it defaults to instance id 0 and returns 0 for time remaining.
|
||||
- Added UpdateZoneHeader(type, value) to Perl and Lua.
|
||||
- Note: UpdateZoneHeader allows you to manipulate fog color, fog density, and many other zone header settings on the fly in Perl and Lua.
|
||||
|
||||
== 12/21/2015 ==
|
||||
Natedog: Updated item table fields and added a few missing fields for evolving items
|
||||
-DO NOT implement Heirloom items till the inventory code is fixed to allow placing NO DROP
|
||||
|
||||
@ -1183,21 +1183,16 @@ bool Database::CheckNameFilter(const char* name, bool surname)
|
||||
{
|
||||
std::string str_name = name;
|
||||
|
||||
if(surname)
|
||||
// the minimum 4 is enforced by the client too
|
||||
if (!name || strlen(name) < 4)
|
||||
{
|
||||
// the minimum 4 is enforced by the client too
|
||||
if(!name || strlen(name) < 3)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else
|
||||
|
||||
// Given name length is enforced by the client too
|
||||
if (!surname && strlen(name) > 15)
|
||||
{
|
||||
// the minimum 4 is enforced by the client too
|
||||
if(!name || strlen(name) < 4 || strlen(name) > 15)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < str_name.size(); i++)
|
||||
@ -1564,7 +1559,7 @@ void Database::AddReport(std::string who, std::string against, std::string lines
|
||||
char *escape_str = new char[lines.size()*2+1];
|
||||
DoEscapeString(escape_str, lines.c_str(), lines.size());
|
||||
|
||||
std::string query = StringFormat("INSERT INTO reports (name, reported, reported_text) VALUES('%s', '%s', '%s')", who.c_str(), against.c_str(), escape_str);
|
||||
std::string query = StringFormat("INSERT INTO reports (name, reported, reported_text) VALUES('%s', '%s', '%s')", EscapeString(who).c_str(), EscapeString(against).c_str(), escape_str);
|
||||
QueryDatabase(query);
|
||||
safe_delete_array(escape_str);
|
||||
}
|
||||
|
||||
@ -493,7 +493,7 @@ bool Database::CheckDatabaseConversions() {
|
||||
/* Check for a new version of this script, the arg passed
|
||||
would have to be higher than the copy they have downloaded
|
||||
locally and they will re fetch */
|
||||
system("perl eqemu_update.pl V 13");
|
||||
system("perl eqemu_update.pl V 14");
|
||||
|
||||
/* Run Automatic Database Upgrade Script */
|
||||
system("perl eqemu_update.pl ran_from_world");
|
||||
|
||||
@ -233,6 +233,8 @@ enum { //some random constants
|
||||
#define GROUP_EXP_PER_POINT 1000
|
||||
#define RAID_EXP_PER_POINT 2000
|
||||
|
||||
#define ZONE_CONTROLLER_NPC_ID 10
|
||||
|
||||
//Some hard coded statuses from commands and other places:
|
||||
enum {
|
||||
minStatusToBeGM = 40,
|
||||
|
||||
@ -236,7 +236,7 @@ void RuleManager::SaveRules(Database *database, const char *ruleset_name) {
|
||||
}
|
||||
|
||||
bool RuleManager::LoadRules(Database *database, const char *ruleset_name) {
|
||||
|
||||
|
||||
int ruleset_id = GetRulesetID(database, ruleset_name);
|
||||
if (ruleset_id < 0) {
|
||||
Log.Out(Logs::Detail, Logs::Rules, "Failed to find ruleset '%s' for load operation. Canceling.", ruleset_name);
|
||||
@ -248,6 +248,26 @@ bool RuleManager::LoadRules(Database *database, const char *ruleset_name) {
|
||||
m_activeRuleset = ruleset_id;
|
||||
m_activeName = ruleset_name;
|
||||
|
||||
/* Load default ruleset values first if we're loading something other than default */
|
||||
if (strcasecmp(ruleset_name, "default") != 0){
|
||||
std::string default_ruleset_name = "default";
|
||||
int default_ruleset_id = GetRulesetID(database, default_ruleset_name.c_str());
|
||||
if (default_ruleset_id < 0) {
|
||||
Log.Out(Logs::Detail, Logs::Rules, "Failed to find default ruleset '%s' for load operation. Canceling.", default_ruleset_name.c_str());
|
||||
return(false);
|
||||
}
|
||||
Log.Out(Logs::Detail, Logs::Rules, "Loading rule set '%s' (%d)", default_ruleset_name.c_str(), default_ruleset_id);
|
||||
|
||||
std::string query = StringFormat("SELECT rule_name, rule_value FROM rule_values WHERE ruleset_id = %d", default_ruleset_id);
|
||||
auto results = database->QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
return false;
|
||||
|
||||
for (auto row = results.begin(); row != results.end(); ++row)
|
||||
if (!SetRule(row[0], row[1], nullptr, false))
|
||||
Log.Out(Logs::Detail, Logs::Rules, "Unable to interpret rule record for %s", row[0]);
|
||||
}
|
||||
|
||||
std::string query = StringFormat("SELECT rule_name, rule_value FROM rule_values WHERE ruleset_id=%d", ruleset_id);
|
||||
auto results = database->QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
|
||||
@ -233,6 +233,7 @@ RULE_BOOL(Zone, LevelBasedEXPMods, false) // Allows you to use the level_exp_mod
|
||||
RULE_INT(Zone, WeatherTimer, 600) // Weather timer when no duration is available
|
||||
RULE_BOOL(Zone, EnableLoggedOffReplenishments, true)
|
||||
RULE_INT(Zone, MinOfflineTimeToReplenishments, 21600) // 21600 seconds is 6 Hours
|
||||
RULE_BOOL(Zone, UseZoneController, true) // Enables the ability to use persistent quest based zone controllers (zone_controller.pl/lua)
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
RULE_CATEGORY(Map)
|
||||
@ -449,7 +450,7 @@ RULE_REAL (Combat,TauntSkillFalloff, 0.33)//For every taunt skill point that's n
|
||||
RULE_BOOL (Combat,EXPFromDmgShield, false) //Determine if damage from a damage shield counts for EXP gain.
|
||||
RULE_INT(Combat, MonkACBonusWeight, 15)
|
||||
RULE_INT(Combat, ClientStunLevel, 55) //This is the level where client kicks and bashes can stun the target
|
||||
RULE_INT(Combat, QuiverWRHasteDiv, 3) //Weight Reduction is divided by this to get haste contribution for quivers
|
||||
RULE_INT(Combat, QuiverHasteCap, 1000) //Quiver haste cap 1000 on live for a while, currently 700 on live
|
||||
RULE_BOOL(Combat, UseArcheryBonusRoll, false) //Make the 51+ archery bonus require an actual roll
|
||||
RULE_INT(Combat, ArcheryBonusChance, 50)
|
||||
RULE_INT(Combat, BerserkerFrenzyStart, 35)
|
||||
@ -461,6 +462,7 @@ RULE_INT(Combat, MeleePushChance, 50) // (NPCs) chance the target will be pushed
|
||||
RULE_BOOL(Combat, UseLiveCombatRounds, true) // turn this false if you don't want to worry about fixing up combat rounds for NPCs
|
||||
RULE_INT(Combat, NPCAssistCap, 5) // Maxiumium number of NPCs that will assist another NPC at once
|
||||
RULE_INT(Combat, NPCAssistCapTimer, 6000) // Time in milliseconds a NPC will take to clear assist aggro cap space
|
||||
RULE_BOOL(Combat, UseRevampHandToHand, false) // use h2h revamped dmg/delays I believe this was implemented during SoF
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
RULE_CATEGORY(NPC)
|
||||
|
||||
@ -1,6 +1,10 @@
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1800
|
||||
#include <algorithm>
|
||||
#endif
|
||||
|
||||
#include "classes.h"
|
||||
#include "eq_packet_structs.h"
|
||||
#include "eqemu_exception.h"
|
||||
@ -954,7 +958,7 @@ void SharedDatabase::LoadItems(void *data, uint32 size, int32 items, uint32 max_
|
||||
item.LDoNPrice = (uint32)atoul(row[ItemField::ldonprice]);
|
||||
item.LDoNSold = (uint32)atoul(row[ItemField::ldonsold]);
|
||||
item.BagType = (uint8)atoi(row[ItemField::bagtype]);
|
||||
item.BagSlots = (uint8)atoi(row[ItemField::bagslots]);
|
||||
item.BagSlots = (uint8)std::min(atoi(row[ItemField::bagslots]), 10); // FIXME: remove when big bags supported
|
||||
item.BagSize = (uint8)atoi(row[ItemField::bagsize]);
|
||||
item.BagWR = (uint8)atoi(row[ItemField::bagwr]);
|
||||
item.Book = (uint8)atoi(row[ItemField::book]);
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
|
||||
*/
|
||||
|
||||
#define CURRENT_BINARY_DATABASE_VERSION 9093
|
||||
#define CURRENT_BINARY_DATABASE_VERSION 9095
|
||||
#ifdef BOTS
|
||||
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9000
|
||||
#else
|
||||
|
||||
@ -23,7 +23,7 @@ if($Config{osname}=~/linux/i){ $OS = "Linux"; }
|
||||
if($Config{osname}=~/Win|MS/i){ $OS = "Windows"; }
|
||||
|
||||
#::: If current version is less than what world is reporting, then download a new one...
|
||||
$current_version = 13;
|
||||
$current_version = 14;
|
||||
|
||||
if($ARGV[0] eq "V"){
|
||||
if($ARGV[1] > $current_version){
|
||||
@ -107,6 +107,38 @@ if($path eq ""){
|
||||
exit;
|
||||
}
|
||||
|
||||
if($ARGV[0] eq "install_peq_db"){
|
||||
|
||||
$db_name = "peq";
|
||||
if($ARGV[1]){
|
||||
$db_name = $ARGV[1];
|
||||
}
|
||||
|
||||
$db = $db_name;
|
||||
|
||||
#::: Database Routines
|
||||
print "MariaDB :: Creating Database '" . $db_name . "'\n";
|
||||
print `"$path" --host $host --user $user --password="$pass" -N -B -e "DROP DATABASE IF EXISTS $db_name;"`;
|
||||
print `"$path" --host $host --user $user --password="$pass" -N -B -e "CREATE DATABASE $db_name"`;
|
||||
if($OS eq "Windows"){ @db_version = split(': ', `world db_version`); }
|
||||
if($OS eq "Linux"){ @db_version = split(': ', `./world db_version`); }
|
||||
$bin_db_ver = trim($db_version[1]);
|
||||
check_db_version_table();
|
||||
$local_db_ver = trim(get_mysql_result("SELECT version FROM db_version LIMIT 1"));
|
||||
fetch_peq_db_full();
|
||||
print "\nFetching Latest Database Updates...\n";
|
||||
main_db_management();
|
||||
print "\nApplying Latest Database Updates...\n";
|
||||
main_db_management();
|
||||
|
||||
print get_mysql_result("UPDATE `launcher` SET `dynamics` = 30 WHERE `name` = 'zone'");
|
||||
}
|
||||
|
||||
if($ARGV[0] eq "remove_duplicate_rules"){
|
||||
remove_duplicate_rule_values();
|
||||
exit;
|
||||
}
|
||||
|
||||
if($ARGV[0] eq "installer"){
|
||||
print "Running EQEmu Server installer routines...\n";
|
||||
mkdir('logs');
|
||||
@ -152,6 +184,7 @@ if($ARGV[0] eq "installer"){
|
||||
|
||||
if($OS eq "Windows"){
|
||||
check_windows_firewall_rules();
|
||||
do_windows_login_server_setup();
|
||||
}
|
||||
exit;
|
||||
}
|
||||
@ -251,6 +284,7 @@ sub show_menu_prompt {
|
||||
11 => \&fetch_latest_windows_binaries,
|
||||
12 => \&fetch_server_dlls,
|
||||
13 => \&do_windows_login_server_setup,
|
||||
14 => \&remove_duplicate_rule_values,
|
||||
19 => \&do_bots_db_schema_drop,
|
||||
20 => \&do_update_self,
|
||||
0 => \&script_exit,
|
||||
@ -328,6 +362,7 @@ return <<EO_MENU;
|
||||
11) [Windows Server Build] :: Download Latest and Stable Server Build (Overwrites existing .exe's, includes .dll's)
|
||||
12) [Windows Server .dll's] :: Download Pre-Requisite Server .dll's
|
||||
13) [Windows Server Loginserver Setup] :: Download and install Windows Loginserver
|
||||
14) [Remove Duplicate Rule Values] :: Looks for redundant rule_values entries and removes them
|
||||
19) [EQEmu DB Drop Bots Schema] :: Remove Bots schema and return database to normal state
|
||||
20) [Update the updater] Force update this script (Redownload)
|
||||
0) Exit
|
||||
@ -521,6 +556,33 @@ sub opcodes_fetch{
|
||||
print "\nDone...\n\n";
|
||||
}
|
||||
|
||||
sub remove_duplicate_rule_values{
|
||||
$ruleset_id = trim(get_mysql_result("SELECT `ruleset_id` FROM `rule_sets` WHERE `name` = 'default'"));
|
||||
print "Default Ruleset ID: " . $ruleset_id . "\n";
|
||||
|
||||
$total_removed = 0;
|
||||
#::: Store Default values...
|
||||
$mysql_result = get_mysql_result("SELECT * FROM `rule_values` WHERE `ruleset_id` = " . $ruleset_id);
|
||||
my @lines = split("\n", $mysql_result);
|
||||
foreach my $val (@lines){
|
||||
my @values = split("\t", $val);
|
||||
$rule_set_values{$values[1]}[0] = $values[2];
|
||||
}
|
||||
#::: Compare default values against other rulesets to check for duplicates...
|
||||
$mysql_result = get_mysql_result("SELECT * FROM `rule_values` WHERE `ruleset_id` != " . $ruleset_id);
|
||||
my @lines = split("\n", $mysql_result);
|
||||
foreach my $val (@lines){
|
||||
my @values = split("\t", $val);
|
||||
if($values[2] == $rule_set_values{$values[1]}[0]){
|
||||
print "DUPLICATE : " . $values[1] . " (Ruleset (" . $values[0] . ")) matches default value of : " . $values[2] . ", removing...\n";
|
||||
get_mysql_result("DELETE FROM `rule_values` WHERE `ruleset_id` = " . $values[0] . " AND `rule_name` = '" . $values[1] . "'");
|
||||
$total_removed++;
|
||||
}
|
||||
}
|
||||
|
||||
print "Total duplicate rules removed... " . $total_removed . "\n";
|
||||
}
|
||||
|
||||
sub copy_file{
|
||||
$l_source_file = $_[0];
|
||||
$l_dest_file = $_[1];
|
||||
@ -1316,8 +1378,14 @@ sub run_database_check{
|
||||
|
||||
@total_updates = ();
|
||||
|
||||
#::: This is where we set checkpoints for where a database might be so we don't check so far back in the manifest...
|
||||
$revision_check = 1000;
|
||||
if(get_mysql_result("SHOW TABLES LIKE 'character_data'") ne ""){
|
||||
$revision_check = 9000;
|
||||
}
|
||||
|
||||
#::: Iterate through Manifest backwards from binary version down to local version...
|
||||
for($i = $bin_db_ver; $i > 1000; $i--){
|
||||
for($i = $bin_db_ver; $i > $revision_check; $i--){
|
||||
if(!defined($m_d{$i}[0])){ next; }
|
||||
|
||||
$file_name = trim($m_d{$i}[1]);
|
||||
|
||||
@ -111,6 +111,14 @@ sub read_items_file_from_13th_floor_text {
|
||||
print "Processing (" . $read_items_file . ") :: (Items: " . $total_items . "/" . $total_items_file . ") \r";
|
||||
|
||||
printf "\n" . $total_items . " items added to database... Took " . (time() - $start_time) . " second(s)... \n";
|
||||
|
||||
print "Flipping slots 21 and 22...";
|
||||
$rows_affected = $dbh->prepare("
|
||||
UPDATE `items_floor`
|
||||
SET `slots` = (`slots` ^ 6291456)
|
||||
WHERE (`slots` & 6291456)
|
||||
IN (2097152, 4194304)")->execute();
|
||||
print " Rows affected (" . $rows_affected . ")\n";
|
||||
}
|
||||
|
||||
sub update_items_table {
|
||||
|
||||
@ -1,261 +1,261 @@
|
||||
5001|1_task_system.sql
|
||||
5001|1_task_system.sql|SHOW TABLES LIKE 'tasks'|empty|
|
||||
# 5002|2_optional_maxclients.sql
|
||||
# 5003|14_optional_merchantlist.sql
|
||||
5004|35_task_stepped.sql
|
||||
5005|42_task_min_maxlevel.sql
|
||||
5006|55_zone_shutdowndeleay.sql
|
||||
5004|35_task_stepped.sql|SHOW COLUMNS FROM `tasks` LIKE 'stepped'|not_empty|
|
||||
5005|42_task_min_maxlevel.sql|SHOW COLUMNS FROM `tasks` LIKE 'minlevel'|empty|
|
||||
5006|55_zone_shutdowndeleay.sql|SHOW COLUMNS FROM `zone` LIKE 'shutdowndelay'|empty|
|
||||
# 5007|68_optional_character_maxexplevel.sql
|
||||
# 5008|103_optional_chat_rules.sql
|
||||
5009|104_traps.sql
|
||||
5009|104_traps.sql|SHOW COLUMNS FROM `traps` LIKE 'respawn_time'|empty|
|
||||
# 5010|106_optional_proc_rules.sql
|
||||
5011|120_damageshieldtypes.sql
|
||||
5012|125_aggrozone.sql
|
||||
5011|120_damageshieldtypes.sql|SHOW TABLES LIKE 'damageshieldtypes'|empty|
|
||||
# 5012|125_aggrozone.sql
|
||||
# 5013|127_optional_spell_rules.sql
|
||||
# 5014|129_optional_shared_plat_rule.sql
|
||||
# 5015|131_optional_combat_rules.sql
|
||||
5016|133_task_repeatable.sql
|
||||
5017|142_deathpeace_and_lifetap_aas.sql
|
||||
5016|133_task_repeatable.sql|SHOW COLUMNS FROM `tasks` LIKE 'repeatable'|empty|
|
||||
5017|142_deathpeace_and_lifetap_aas.sql|SELECT * FROM db_version WHERE version > 5016|empty|
|
||||
# 5018|158_optional_death_exp_loss.sql
|
||||
5019|176_melody.sql
|
||||
5020|189_character_.sql
|
||||
5021|196_trader.sql
|
||||
5022|210_undyeme.sql
|
||||
5023|222_buyer.sql
|
||||
5024|226_account_limiting.sql
|
||||
5025|230_spells_table.sql
|
||||
5026|235_horses_table.sql
|
||||
5027|243_spawn_timers.sql
|
||||
5028|247_mail.sql
|
||||
5029|249_chatchannels.sql
|
||||
5030|250_bot_spell_update.sql
|
||||
# 5019|176_melody.sql
|
||||
5020|189_character_.sql|SELECT * FROM db_version WHERE version >= 5020|empty|
|
||||
5021|196_trader.sql|SHOW TABLES LIKE 'trader'|empty|
|
||||
# 5022|210_undyeme.sql
|
||||
5023|222_buyer.sql|SHOW TABLES LIKE 'buyer'|empty|
|
||||
# 5024|226_account_limiting.sql
|
||||
5025|230_spells_table.sql|SHOW TABLES LIKE 'spells_new'|empty|
|
||||
5026|235_horses_table.sql|SHOW TABLES LIKE 'horses'|empty|
|
||||
5027|243_spawn_timers.sql|SHOW TABLES LIKE 'respawn_times'|empty|
|
||||
5028|247_mail.sql|SHOW TABLES LIKE 'mail'|empty|
|
||||
5029|249_chatchannels.sql|SHOW TABLES LIKE 'chatchannels'|empty|
|
||||
# 5030|250_bot_spell_update.sql
|
||||
# 5031|250_optional_bot_spell_update.sql
|
||||
# 5032|285_optional_bot_spell_update.sql
|
||||
5033|292_augslots.sql
|
||||
5034|294_merchant_logging.sql
|
||||
5035|304_faction_list.sql
|
||||
5036|326_aas.sql
|
||||
5037|328_bot_management.sql
|
||||
# 5033|292_augslots.sql|SELECT * FROM db_version WHERE version >= 5033|empty|
|
||||
5034|294_merchant_logging.sql|SHOW COLUMNS FROM `eventlog` LIKE 'event_nid'|empty|
|
||||
5035|304_faction_list.sql|SELECT * FROM db_version WHERE version >= 5035|empty|
|
||||
5036|326_aas.sql|SELECT * FROM db_version WHERE version > 5035|empty|
|
||||
# 5037|328_bot_management.sql
|
||||
# 5038|328_optional_bot_management.sql
|
||||
5039|340_gm_ips.sql
|
||||
5040|356_combat.sql
|
||||
5041|360_peqzone.sql
|
||||
5042|364_ranged_dist_rule.sql
|
||||
5043|386_bot_save_raid.sql
|
||||
5039|340_gm_ips.sql|SHOW TABLES LIKE 'gm_ips'|empty|
|
||||
# 5040|356_combat.sql
|
||||
# 5041|360_peqzone.sql
|
||||
# 5042|364_ranged_dist_rule.sql
|
||||
# 5043|386_bot_save_raid.sql
|
||||
# 5044|434_optional_rest_state_rules.sql
|
||||
5045|447_sof_startzone_rule.sql
|
||||
5046|463_altadv_vars.sql
|
||||
5047|475_aa_actions.sql
|
||||
5048|500_spawn2_optimization.sql
|
||||
5049|503_bugs.sql
|
||||
5050|518_drakkin_npc_type_features.sql
|
||||
5051|524_rule_values_notes.sql
|
||||
5052|527_npc_armor_tint.sql
|
||||
5053|553_saylink_table.sql
|
||||
5054|564_nokeyring.sql
|
||||
5055|600_group_leadership.sql
|
||||
5056|612_instance_changes.sql
|
||||
5057|615_adventure_assassination.sql
|
||||
5058|619_Adventure_Recruiter_Flavor.sql
|
||||
5059|621_LDoNTraps.sql
|
||||
5060|633_ucs.sql
|
||||
5061|634_TrapTemplateDefaultValue.sql
|
||||
5062|643_BotsTable.sql
|
||||
5063|646_archery_penalty_rule.sql
|
||||
5064|665_heroic_resists.sql
|
||||
5065|667_titles.sql
|
||||
5066|687_aa_table_changes.sql
|
||||
5067|699_peqzone_rule.sql
|
||||
5068|702_aashieldblock_tint_table.sql
|
||||
5069|703_peqzone_rule.sql
|
||||
5070|704_rules.sql
|
||||
5071|710_tint_set_naming.sql
|
||||
5072|721_pathing_rules.sql
|
||||
5073|730_smart_delay_moving.sql
|
||||
5074|731_rule_assist_notarget_self.sql
|
||||
5075|732_sacrifice_rules.sql
|
||||
5076|745_slow_mitigation.sql
|
||||
5077|754_archery_base_damage_rule.sql
|
||||
5078|755_sof_altadv_vars_updates.sql
|
||||
5079|773_monk_rules.sql
|
||||
# 5045|447_sof_startzone_rule.sql
|
||||
# 5046|463_altadv_vars.sql
|
||||
# 5047|475_aa_actions.sql
|
||||
5048|500_spawn2_optimization.sql|SELECT * FROM db_version WHERE version >= 5048|empty|
|
||||
5049|503_bugs.sql|SHOW TABLES LIKE 'bugs'|empty|
|
||||
5050|518_drakkin_npc_type_features.sql|SHOW TABLES LIKE 'bugs'|empty|
|
||||
5051|524_rule_values_notes.sql|SELECT * FROM db_version WHERE version >= 5051|empty|
|
||||
5052|527_npc_armor_tint.sql|SELECT * FROM db_version WHERE version >= 5052|empty|
|
||||
5053|553_saylink_table.sql|SHOW TABLES LIKE 'saylink'|empty|
|
||||
5054|564_nokeyring.sql|SHOW COLUMNS FROM `doors` LIKE 'nokeyring'|empty|
|
||||
5055|600_group_leadership.sql|SELECT * FROM db_version WHERE version >= 5055|empty|
|
||||
5056|612_instance_changes.sql|SELECT * FROM db_version WHERE version >= 5056|empty|
|
||||
5057|615_adventure_assassination.sql|SELECT * FROM db_version WHERE version >= 5057|empty|
|
||||
5058|619_Adventure_Recruiter_Flavor.sql|SELECT * FROM db_version WHERE version >= 5058|empty|
|
||||
5059|621_LDoNTraps.sql|SHOW TABLES LIKE 'ldon_trap_templates'|empty|
|
||||
5060|633_ucs.sql|SHOW TABLES LIKE 'friends'|empty|
|
||||
5061|634_TrapTemplateDefaultValue.sql|SHOW COLUMNS FROM `npc_types` LIKE 'trap_template'|empty|
|
||||
# 5062|643_BotsTable.sql
|
||||
# 5063|646_archery_penalty_rule.sql
|
||||
5064|665_heroic_resists.sql|SELECT * FROM db_version WHERE version >= 5064|empty|
|
||||
5065|667_titles.sql|SHOW TABLES LIKE 'titles'|empty|
|
||||
5066|687_aa_table_changes.sql|SELECT * FROM db_version WHERE version >= 5066|empty|
|
||||
# 5067|699_peqzone_rule.sql
|
||||
5068|702_aashieldblock_tint_table.sql|SHOW TABLES LIKE 'npc_types_tint'|empty|
|
||||
# 5069|703_peqzone_rule.sql
|
||||
# 5070|704_rules.sql
|
||||
5071|710_tint_set_naming.sql|SELECT * FROM db_version WHERE version >= 5071|empty|
|
||||
5072|721_pathing_rules.sql|SELECT * FROM db_version WHERE version >= 5072|empty|
|
||||
# 5073|730_smart_delay_moving.sql
|
||||
# 5074|731_rule_assist_notarget_self.sql
|
||||
# 5075|732_sacrifice_rules.sql
|
||||
5076|745_slow_mitigation.sql|SELECT * FROM db_version WHERE version >= 5076|empty|
|
||||
# 5077|754_archery_base_damage_rule.sql
|
||||
5078|755_sof_altadv_vars_updates.sql|SELECT * FROM db_version WHERE version >= 5078|empty|
|
||||
# 5079|773_monk_rules.sql
|
||||
# 5080|853_optional_rule_aaexp.sql
|
||||
# 5081|858_optional_rule_ip_limit_by_status.sql
|
||||
# 5082|892_optional_bots_table_mod.sql
|
||||
# 5083|893_optional_bots_table_mod.sql
|
||||
5084|898_npc_maxlevel_scalerate.sql
|
||||
5084|898_npc_maxlevel_scalerate.sql|SHOW COLUMNS FROM `npc_types` LIKE 'maxlevel'|empty|
|
||||
# 5085|902_optional_rule_snareflee.sql
|
||||
5086|923_spawn2_enabled.sql
|
||||
5087|962_hot_zone.sql
|
||||
5088|964_reports.sql
|
||||
5089|971_veteran_rewards.sql
|
||||
5090|977_raid_npc_private_corpses.sql
|
||||
5091|979_unique_spawn_by_name.sql
|
||||
5092|980_account_ip.sql
|
||||
5093|1022_botadventuring.sql
|
||||
5094|1027_botactives.sql
|
||||
5095|1030_botzoningsupport.sql
|
||||
5096|1036_botbuffs.sql
|
||||
5097|1038_botpetstatepersists.sql
|
||||
5098|1038_grouptablesuniquecolumndefinitions.sql
|
||||
5099|1039_botguilds.sql
|
||||
5100|1040_DeprecatedBotRaidsSystems.sql
|
||||
5101|1057_titles.sql
|
||||
5102|1077_botgroups.sql
|
||||
5103|1136_spell_globals.sql
|
||||
5086|923_spawn2_enabled.sql|SHOW COLUMNS FROM `spawn2` LIKE 'enabled'|empty|
|
||||
5087|962_hot_zone.sql|SHOW COLUMNS FROM `zone` LIKE 'hotzone'|empty|
|
||||
5088|964_reports.sql|SHOW TABLES LIKE 'reports'|empty|
|
||||
5089|971_veteran_rewards.sql|SHOW TABLES LIKE 'veteran_reward_templates'|empty|
|
||||
5090|977_raid_npc_private_corpses.sql|SELECT * FROM db_version WHERE version >= 5090|empty|
|
||||
5091|979_unique_spawn_by_name.sql|SHOW COLUMNS FROM `npc_types` LIKE 'unique_spawn_by_name'|empty|
|
||||
5092|980_account_ip.sql|SHOW TABLES LIKE 'account_ip'|empty|
|
||||
# 5093|1022_botadventuring.sql
|
||||
# 5094|1027_botactives.sql
|
||||
# 5095|1030_botzoningsupport.sql
|
||||
# 5096|1036_botbuffs.sql
|
||||
# 5097|1038_botpetstatepersists.sql
|
||||
5098|1038_grouptablesuniquecolumndefinitions.sql|SELECT * FROM db_version WHERE version >= 5098|empty|
|
||||
# 5099|1039_botguilds.sql
|
||||
# 5100|1040_DeprecatedBotRaidsSystems.sql
|
||||
5101|1057_titles.sql|SHOW TABLES LIKE 'player_titlesets'|empty|
|
||||
# 5102|1077_botgroups.sql
|
||||
5103|1136_spell_globals.sql|SHOW TABLES LIKE 'spell_globals'|empty|
|
||||
# 5104|1144_optional_rule_return_nodrop.sql
|
||||
5105|1195_account_suspendeduntil.sql
|
||||
5106|1259_npc_skill_types.sql
|
||||
5107|1280_bot_augs.sql
|
||||
5105|1195_account_suspendeduntil.sql|SELECT * FROM db_version WHERE version >= 5105|empty|
|
||||
5106|1259_npc_skill_types.sql|SHOW COLUMNS FROM `npc_types` LIKE 'prim_melee_type'|empty|
|
||||
# 5107|1280_bot_augs.sql
|
||||
# 5108|1290_optional_exp_loss_rule.sql
|
||||
5109|1293_guild_bank.sql
|
||||
5110|1379_loginserver_trusted_server.sql
|
||||
5111|1392_recipe_learning.sql
|
||||
5109|1293_guild_bank.sql|SHOW TABLES LIKE 'guild_bank'|empty|
|
||||
# 5110|1379_loginserver_trusted_server.sql
|
||||
5111|1392_recipe_learning.sql|SELECT * FROM db_version WHERE version >= 5111|empty|
|
||||
# 5112|1394_optional_rule_sod_hp_mana_end.sql
|
||||
5113|1404_faction_list.sql
|
||||
5113|1404_faction_list.sql|SELECT * FROM db_version WHERE version >= 5113|empty|
|
||||
# 5114|1410_optional_sod_aas_ht_and_loh.sql
|
||||
5115|1436_login_server_table_fix.sql
|
||||
5116|1446_allowrest_optional.sql
|
||||
5117|1446_allowrest_required.sql
|
||||
5118|1450_cvs.sql
|
||||
5119|1451_guilds.sql
|
||||
5120|1498_instance_adventure.sql
|
||||
5121|1510_global_instances.sql
|
||||
5122|1511_map_path_loading.sql
|
||||
5123|1513_zone_points.sql
|
||||
5124|1519_zone_primary_key_id.sql
|
||||
5125|1542_items_table_cleanup.sql
|
||||
5126|1548_nimbuseffect_required.sql
|
||||
5127|1562_instanced_spawnconditions.sql
|
||||
5128|1586_waypoints_optional.sql
|
||||
5129|1610_tradeskill_required.sql
|
||||
5130|1618_zone.sql
|
||||
# 5115|1436_login_server_table_fix.sql
|
||||
# 5116|1446_allowrest_optional.sql
|
||||
5117|1446_allowrest_required.sql|SELECT * FROM db_version WHERE version >= 5117|empty|
|
||||
# 5118|1450_cvs.sql
|
||||
5119|1451_guilds.sql|SELECT * FROM db_version WHERE version >= 5119|empty|
|
||||
5120|1498_instance_adventure.sql|SELECT * FROM db_version WHERE version >= 5120|empty|
|
||||
5121|1510_global_instances.sql|SELECT * FROM db_version WHERE version >= 5121|empty|
|
||||
5122|1511_map_path_loading.sql|SHOW COLUMNS FROM `zone` LIKE 'map_file_name'|empty|
|
||||
5123|1513_zone_points.sql|SELECT * FROM db_version WHERE version >= 5123|empty|
|
||||
5124|1519_zone_primary_key_id.sql|SELECT * FROM db_version WHERE version >= 5124|empty|
|
||||
5125|1542_items_table_cleanup.sql|SELECT * FROM db_version WHERE version >= 5125|empty|
|
||||
5126|1548_nimbuseffect_required.sql|SELECT * FROM db_version WHERE version >= 5126|empty|
|
||||
5127|1562_instanced_spawnconditions.sql|SHOW TABLES LIKE 'spawn_condition_values'|empty|
|
||||
# 5128|1586_waypoints_optional.sql
|
||||
5129|1610_tradeskill_required.sql|SELECT * FROM db_version WHERE version >= 5129|empty|
|
||||
5130|1618_zone.sql|SELECT * FROM db_version WHERE version >= 5130|empty|
|
||||
# 5131|1625_optional_rule_class_race_exp_bonus.sql
|
||||
# 5132|1672_optional_rules_respawn_window.sql
|
||||
# 5133|1679_optional_rules_blocked_buffs.sql
|
||||
5134|1696_modify_zone_and_object_tables.sql
|
||||
5135|1711_account_restricted_aa.sql
|
||||
5134|1696_modify_zone_and_object_tables.sql|SELECT * FROM db_version WHERE version >= 5134|empty|
|
||||
5135|1711_account_restricted_aa.sql|SHOW COLUMNS FROM `account` LIKE 'time_creation'|empty|
|
||||
# 5136|1717_optional_rule_bash_stun_chance.sql
|
||||
# 5137|1718_optional_rules_mod3s.sql
|
||||
# 5138|1719_optional_triggerOnCastAAs.sql
|
||||
# 5139|1720_optional_sql_AAs.sql
|
||||
5140|1720_required_sql_AA_effects_update.sql
|
||||
# 5140|1720_required_sql_AA_effects_update.sql
|
||||
# 5141|1721_optional_sql_drakkin_breath_update.sql
|
||||
5142|1721_required_sql_altadv_vars_update.sql
|
||||
# 5142|1721_required_sql_altadv_vars_update.sql
|
||||
# 5143|1723_optional_sql_new_stats_window_rule.sql
|
||||
5144|1723_required_sql_corruption.sql
|
||||
5144|1723_required_sql_corruption.sql|SELECT * FROM db_version WHERE version >= 5144|empty|
|
||||
# 5145|1736_optional_sql_feral_swipe.sql
|
||||
5146|1737_required_sql_rule_and_aa_update.sql
|
||||
# 5146|1737_required_sql_rule_and_aa_update.sql
|
||||
# 5147|1746_optional_sql_bot_manaregen.sql
|
||||
# 5148|1747_optional_HoT_zone_and_zonepoints.sql
|
||||
# 5149|1750_optional_sql_reflect_rule.sql
|
||||
# 5150|1753_optional_haste_cap_rule.sql
|
||||
5151|1753_required_sql_healing_adept_aa.sql
|
||||
5152|1754_required_sql_healing_adept_aa_fix.sql
|
||||
5153|1755_required_sql_fear_resist_aas.sql
|
||||
# 5151|1753_required_sql_healing_adept_aa.sql
|
||||
# 5152|1754_required_sql_healing_adept_aa_fix.sql
|
||||
# 5153|1755_required_sql_fear_resist_aas.sql
|
||||
# 5154|1784_optional_corpsedrag_rules.sql
|
||||
5155|1786_required_update_to_aas.sql
|
||||
5156|1790_required_aa_required_level_cost.sql
|
||||
5157|1793_resist_adjust.sql
|
||||
# 5155|1786_required_update_to_aas.sql
|
||||
# 5156|1790_required_aa_required_level_cost.sql
|
||||
5157|1793_resist_adjust.sql|SHOW COLUMNS FROM `npc_spells_entries` LIKE 'resist_adjust'|empty|
|
||||
# 5158|1799_optional_rest_regen_endurance_rule.sql
|
||||
5159|1802_required_doppelganger.sql
|
||||
5160|1803_required_tasks_xpreward_signed.sql
|
||||
5161|1804_required_ae_melee_updates.sql
|
||||
5159|1802_required_doppelganger.sql|SELECT * FROM db_version WHERE version >= 5159|empty|
|
||||
5160|1803_required_tasks_xpreward_signed.sql|SELECT * FROM db_version WHERE version >= 5160|empty|
|
||||
5161|1804_required_ae_melee_updates.sql|SELECT * FROM db_version WHERE version >= 5161|empty|
|
||||
# 5162|1809_optional_rules.sql
|
||||
5163|1813_required_doppelganger_npcid_change.sql
|
||||
5163|1813_required_doppelganger_npcid_change.sql|SELECT * FROM db_version WHERE version >= 5163|empty|
|
||||
# 5164|1817_optional_npc_archery_bonus_rule.sql
|
||||
# 5165|1823_optional_delay_death.sql
|
||||
5166|1847_required_doors_dest_zone_size_32.sql
|
||||
5166|1847_required_doors_dest_zone_size_32.sql|SELECT * FROM db_version WHERE version >= 5166|empty|
|
||||
# 5167|1859_optional_item_casts_use_focus_rule.sql
|
||||
# 5168|1884_optional_bot_spells_update.sql
|
||||
# 5169|1885_optional_rules_fv_pvp_expansions.sql
|
||||
# 5170|1889_optional_skill_cap_rule.sql
|
||||
5171|1908_required_npc_types_definitions.sql
|
||||
5171|1908_required_npc_types_definitions.sql|SHOW COLUMNS FROM `npc_types` LIKE 'attack_count'|empty|
|
||||
# 5172|1926_optional_stat_cap.sql
|
||||
5173|1944_spawn2.sql
|
||||
5174|1946_doors.sql
|
||||
5173|1944_spawn2.sql|SHOW COLUMNS FROM `spawn2` LIKE 'animation'|empty|
|
||||
5174|1946_doors.sql|SELECT * FROM db_version WHERE version >= 5166|empty|
|
||||
# 5175|1960_optional_console_timeout_rule.sql
|
||||
# 5176|1962_optional_guild_creation_window_rules.sql
|
||||
# 5177|1963_optional_rule_live_like_focuses.sql
|
||||
# 5178|1968_optional_enrage_rules.sql
|
||||
# 5179|1972_optional_extradmg_item_cap.sql
|
||||
5180|1974_required_bot_spells_update.sql
|
||||
5181|1977_underwater.sql
|
||||
# 5180|1974_required_bot_spells_update.sql
|
||||
5181|1977_underwater.sql|SHOW COLUMNS FROM `npc_types` LIKE 'underwater'|empty|
|
||||
# 5182|1998_optional_intoxication_and_looting_rules.sql
|
||||
5183|2004_charges_alt_currency.sql
|
||||
5183|2004_charges_alt_currency.sql|SHOW TABLES LIKE 'alternate_currency'|empty|
|
||||
# 5184|2015_optional_specialization_training_rule.sql
|
||||
# 5185|2016_optional_rule_bot_aa_expansion.sql
|
||||
# 5186|2023_optional_mysqlcli.sql
|
||||
# 5187|2024_optional_update_crystals.sql
|
||||
5188|2024_required_update.sql
|
||||
5189|2057_required_discovered_items.sql
|
||||
5188|2024_required_update.sql|SHOW TABLES LIKE 'char_create_combinations'|empty|
|
||||
5189|2057_required_discovered_items.sql|SHOW TABLES LIKE 'discovered_items'|empty|
|
||||
# 5190|2058_optional_rule_discovered_items.sql
|
||||
5191|2062_required_version_changes.sql
|
||||
5192|2069_required_pets.sql
|
||||
5193|2079_player_speech.sql
|
||||
5194|2087_required_bots_hp_and_mana_and_spell_updates.sql
|
||||
5195|2098_required_zonepoint_version_changes.sql
|
||||
5196|2099_required_discovered_items_account_status.sql
|
||||
5197|2104_required_group_roles.sql
|
||||
5198|2107_required_bot_stances.sql
|
||||
5199|2129_required_lfguild.sql
|
||||
5200|2133_required_faction_loot_despawn.sql
|
||||
5201|2136_extended_targets.sql
|
||||
5202|2142_emotes.sql
|
||||
5191|2062_required_version_changes.sql|SELECT * FROM db_version WHERE version >= 5191|empty|
|
||||
5192|2069_required_pets.sql|SHOW TABLES LIKE 'pets_equipmentset'|empty|
|
||||
# 5193|2079_player_speech.sql
|
||||
# 5194|2087_required_bots_hp_and_mana_and_spell_updates.sql
|
||||
5195|2098_required_zonepoint_version_changes.sql|SELECT * FROM db_version WHERE version >= 5195|empty|
|
||||
5196|2099_required_discovered_items_account_status.sql|SELECT * FROM db_version WHERE version >= 5196|empty|
|
||||
5197|2104_required_group_roles.sql|SELECT * FROM db_version WHERE version >= 5197|empty|
|
||||
# 5198|2107_required_bot_stances.sql
|
||||
5199|2129_required_lfguild.sql|SHOW TABLES LIKE 'lfguild'|empty|
|
||||
5200|2133_required_faction_loot_despawn.sql|SELECT * FROM db_version WHERE version >= 5200|empty|
|
||||
5201|2136_extended_targets.sql|SELECT * FROM db_version WHERE version >= 5201|empty|
|
||||
5202|2142_emotes.sql|SELECT * FROM db_version WHERE version >= 5202|empty|
|
||||
# 5203|2154_optional_rule_spell_procs_resists_falloff.sql
|
||||
# 5204|2156_optional_charm_break_rule.sql
|
||||
# 5205|2159_optional_defensiveproc_rules.sql
|
||||
5206|2164_require_bots_bottimers.sql
|
||||
# 5206|2164_require_bots_bottimers.sql
|
||||
# 5207|2171_optional_SpecialAttackACBonus_rule.sql
|
||||
# 5208|2176_optional_aa_expansion_SOF_fix.sql
|
||||
# 5209|2176_optional_FrenzyBonus_rule.sql
|
||||
5210|2176_required_aa_updates.sql
|
||||
5211|2178_required_aa_updates.sql
|
||||
5210|2176_required_aa_updates.sql|SELECT * FROM db_version WHERE version >= 5210|empty|
|
||||
5211|2178_required_aa_updates.sql|SELECT * FROM db_version WHERE version >= 5211|empty|
|
||||
# 5212|2183_optional_bot_xp_rule.sql
|
||||
# 5213|2185_optional_NPCFlurryChacne_rule
|
||||
# 5214|2185_optional_NPCFlurryChacne_rule.sql
|
||||
# 5215|2185_optional_NPCFlurryChance_rule.sql
|
||||
5216|2185_required_aa_updates
|
||||
5217|2185_required_aa_updates.sql
|
||||
5216|2185_required_aa_updates|SELECT * FROM db_version WHERE version >= 5216|empty|
|
||||
5217|2185_required_aa_updates.sql|SELECT * FROM db_version WHERE version >= 5217|empty|
|
||||
# 5218|2188_optional_miscspelleffect_rules
|
||||
# 5219|2188_optional_miscspelleffect_rules.sql
|
||||
5220|2188_required_aa_updates
|
||||
5221|2188_required_aa_updates.sql
|
||||
# 5220|2188_required_aa_updates
|
||||
5221|2188_required_aa_updates.sql|SELECT * FROM db_version WHERE version >= 5221|empty|
|
||||
# 5222|2189_optional_taunt_rules
|
||||
# 5223|2189_optional_taunt_rules.sql
|
||||
5224|2195_required_sharedplatupdates.sql
|
||||
5224|2195_required_sharedplatupdates.sql|SELECT * FROM db_version WHERE version >= 5224|empty|
|
||||
# 5225|2208_optional_aa_stacking_rule.sql
|
||||
# 5226|2208_optional_EnableSoulAbrasionAA.sql
|
||||
5227|2208_required_aa_updates.sql
|
||||
5227|2208_required_aa_updates.sql|SELECT * FROM db_version WHERE version >= 5227|empty|
|
||||
# 5228|2209_optional_additive_bonus_rule.sql
|
||||
5229|2213_loot_changes.sql
|
||||
5230|2214_faction_list_mod.sql
|
||||
5231|2215_required_aa_updates.sql
|
||||
5229|2213_loot_changes.sql|SELECT * FROM db_version WHERE version >= 5229|empty|
|
||||
5230|2214_faction_list_mod.sql|SHOW TABLES LIKE 'faction_list_mod'|empty|
|
||||
5231|2215_required_aa_updates.sql|SELECT * FROM db_version WHERE version >= 5231|empty|
|
||||
# 5232|2243_optional_char_max_level_rule.sql
|
||||
5233|2260_probability.sql
|
||||
5234|2262_required_pet_discipline_update.sql
|
||||
5235|2264_required_aa_updates.sql
|
||||
5236|2268_QueryServ.sql
|
||||
5237|2268_required_updates.sql
|
||||
# 5233|2260_probability.sql
|
||||
5234|2262_required_pet_discipline_update.sql|SELECT * FROM db_version WHERE version >= 5234|empty|
|
||||
5235|2264_required_aa_updates.sql|SELECT * FROM db_version WHERE version >= 5235|empty|
|
||||
# 5236|2268_QueryServ.sql
|
||||
5237|2268_required_updates.sql|SELECT * FROM db_version WHERE version >= 5237|empty|
|
||||
# 5238|2274_optional_rule_iplimitdisconnectall.sql
|
||||
# 5239|2278_optional_rule_targetableswarmpet.sql
|
||||
# 5240|2280_optional_rule_targetableswarmpet-rename.sql
|
||||
5241|2283_required_npc_changes.sql
|
||||
5242|2299_required_inspectmessage_fields.sql
|
||||
5241|2283_required_npc_changes.sql|SHOW COLUMNS FROM `npc_types` LIKE 'spellscale'|empty|
|
||||
5242|2299_required_inspectmessage_fields.sql|SELECT * FROM db_version WHERE version >= 5242|empty|
|
||||
# 5243|2300_optional_loot_changes.sql
|
||||
5244|2304_QueryServ.sql
|
||||
5245|2340_required_maxbuffslotspet.sql
|
||||
5246|2361_QueryServ.sql
|
||||
5247|2361_required_qs_rule_values.sql
|
||||
5248|2370_required_aa_updates.sql
|
||||
5249|2376_required_aa_updates.sql
|
||||
# 5250|2380_optional_merc_data.sql
|
||||
# 5251|2380_optional_merc_merchant_npctypes_update.sql
|
||||
# 5252|2380_optional_merc_rules.sql
|
||||
5253|2383_required_group_ismerc.sql
|
||||
# 5244|2304_QueryServ.sql
|
||||
# 5245|2340_required_maxbuffslotspet.sql
|
||||
# 5246|2361_QueryServ.sql
|
||||
# 5247|2361_required_qs_rule_values.sql
|
||||
5248|2370_required_aa_updates.sql|SELECT * FROM db_version WHERE version >= 5248|empty|
|
||||
5249|2376_required_aa_updates.sql|SELECT * FROM db_version WHERE version >= 5249|empty|
|
||||
5250|2380_optional_merc_data.sql|SELECT * FROM db_version WHERE version >= 5250|empty|
|
||||
5251|2380_optional_merc_merchant_npctypes_update.sql|SELECT * FROM db_version WHERE version >= 5251|empty|
|
||||
5252|2380_optional_merc_rules.sql|SELECT * FROM db_version WHERE version >= 5252|empty|
|
||||
5253|2383_required_group_ismerc.sql|SELECT * FROM db_version WHERE version >= 5253|empty|
|
||||
# 5254|2428_optional_levelbasedexpmods.sql
|
||||
# 5255|2448_optional_stun_proc_aggro_rule.sql
|
||||
5256|2471_required_aa_updates.sql
|
||||
5257|2482_required_start_zones.sql
|
||||
5258|2504_required_aa_updates.sql
|
||||
5256|2471_required_aa_updates.sql|SELECT * FROM db_version WHERE version >= 5256|empty|
|
||||
5257|2482_required_start_zones.sql|SELECT * FROM db_version WHERE version >= 5257|empty|
|
||||
5258|2504_required_aa_updates.sql|SELECT * FROM db_version WHERE version >= 5258|empty|
|
||||
8000|mercs.sql|SHOW TABLES LIKE 'merc_stats'|empty|
|
||||
9000|2013_02_18_Merc_Rules_and_Tables.sql|SELECT * FROM `rule_values` WHERE `rule_name` LIKE '%Mercs:ResurrectRadius%'|empty|
|
||||
9001|2013_02_25_Impr_HT_LT.sql|SHOW TABLES LIKE 'merc_inventory'|empty|
|
||||
@ -347,6 +347,8 @@
|
||||
9091|2015_12_07_command_settings.sql|SHOW TABLES LIKE 'command_settings'|empty|
|
||||
9092|2015_12_17_eqtime.sql|SHOW TABLES LIKE 'eqtime'|empty|
|
||||
9093|2015_12_21_items_updates_evoitem.sql|SHOW COLUMNS FROM `items` LIKE 'evoitem'|empty|
|
||||
9094|2015_12_29_quest_zone_events.sql|SELECT * FROM perl_event_export_settings WHERE event_description = 'EVENT_SPAWN_ZONE'|empty|
|
||||
9095|2016_01_08_command_find_aliases.sql|SELECT * FROM `command_settings` WHERE `command` LIKE 'findaliases'|empty|
|
||||
|
||||
# Upgrade conditions:
|
||||
# This won't be needed after this system is implemented, but it is used database that are not
|
||||
|
||||
4
utils/sql/git/required/2015_12_29_quest_zone_events.sql
Normal file
4
utils/sql/git/required/2015_12_29_quest_zone_events.sql
Normal file
@ -0,0 +1,4 @@
|
||||
INSERT INTO `perl_event_export_settings` (`event_id`, `event_description`, `export_qglobals`, `export_mob`, `export_zone`, `export_item`, `export_event`) VALUES (81, 'EVENT_SPAWN_ZONE', 0, 0, 0, 0, 1);
|
||||
INSERT INTO `perl_event_export_settings` (`event_id`, `event_description`, `export_qglobals`, `export_mob`, `export_zone`, `export_item`, `export_event`) VALUES (82, 'EVENT_DEATH_ZONE', 0, 0, 0, 0, 1);
|
||||
ALTER TABLE `rule_values`
|
||||
MODIFY COLUMN `notes` text CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL AFTER `rule_value`;
|
||||
@ -0,0 +1 @@
|
||||
INSERT INTO `command_settings` VALUES ('findaliases', 0, 'fa');
|
||||
@ -482,7 +482,7 @@ int main(int argc, char** argv) {
|
||||
if (!database.SaveTime(tod.minute, tod.hour, tod.day, tod.month, tod.year))
|
||||
Log.Out(Logs::General, Logs::World_Server, "Failed to save eqtime.");
|
||||
else
|
||||
Log.Out(Logs::General, Logs::World_Server, "EQTime successfully saved.");
|
||||
Log.Out(Logs::Detail, Logs::World_Server, "EQTime successfully saved.");
|
||||
}
|
||||
|
||||
//check for timeouts in other threads
|
||||
|
||||
301
zone/attack.cpp
301
zone/attack.cpp
@ -846,7 +846,7 @@ int Mob::GetWeaponDamage(Mob *against, const Item_Struct *weapon_item) {
|
||||
}
|
||||
else{
|
||||
if((GetClass() == MONK || GetClass() == BEASTLORD) && GetLevel() >= 30){
|
||||
dmg = GetMonkHandToHandDamage();
|
||||
dmg = GetHandToHandDamage();
|
||||
}
|
||||
else if(GetOwner() && GetLevel() >= RuleI(Combat, PetAttackMagicLevel)){
|
||||
//pets wouldn't actually use this but...
|
||||
@ -868,12 +868,7 @@ int Mob::GetWeaponDamage(Mob *against, const Item_Struct *weapon_item) {
|
||||
dmg = dmg <= 0 ? 1 : dmg;
|
||||
}
|
||||
else{
|
||||
if(GetClass() == MONK || GetClass() == BEASTLORD){
|
||||
dmg = GetMonkHandToHandDamage();
|
||||
}
|
||||
else{
|
||||
dmg = 1;
|
||||
}
|
||||
dmg = GetHandToHandDamage();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1006,7 +1001,7 @@ int Mob::GetWeaponDamage(Mob *against, const ItemInst *weapon_item, uint32 *hate
|
||||
|
||||
if((GetClass() == MONK || GetClass() == BEASTLORD)) {
|
||||
if(MagicGloves || GetLevel() >= 30){
|
||||
dmg = GetMonkHandToHandDamage();
|
||||
dmg = GetHandToHandDamage();
|
||||
if (hate) *hate += dmg;
|
||||
}
|
||||
}
|
||||
@ -1041,13 +1036,8 @@ int Mob::GetWeaponDamage(Mob *against, const ItemInst *weapon_item, uint32 *hate
|
||||
}
|
||||
}
|
||||
else{
|
||||
if(GetClass() == MONK || GetClass() == BEASTLORD){
|
||||
dmg = GetMonkHandToHandDamage();
|
||||
if (hate) *hate += dmg;
|
||||
}
|
||||
else{
|
||||
dmg = 1;
|
||||
}
|
||||
dmg = GetHandToHandDamage();
|
||||
if (hate) *hate += dmg;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2009,15 +1999,15 @@ void NPC::Damage(Mob* other, int32 damage, uint16 spell_id, SkillUseTypes attack
|
||||
}
|
||||
}
|
||||
|
||||
bool NPC::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes attack_skill) {
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Fatal blow dealt by %s with %d damage, spell %d, skill %d", killerMob->GetName(), damage, spell, attack_skill);
|
||||
bool NPC::Death(Mob* killer_mob, int32 damage, uint16 spell, SkillUseTypes attack_skill) {
|
||||
Log.Out(Logs::Detail, Logs::Combat, "Fatal blow dealt by %s with %d damage, spell %d, skill %d", killer_mob->GetName(), damage, spell, attack_skill);
|
||||
|
||||
Mob *oos = nullptr;
|
||||
if(killerMob) {
|
||||
oos = killerMob->GetOwnerOrSelf();
|
||||
if(killer_mob) {
|
||||
oos = killer_mob->GetOwnerOrSelf();
|
||||
|
||||
char buffer[48] = { 0 };
|
||||
snprintf(buffer, 47, "%d %d %d %d", killerMob ? killerMob->GetID() : 0, damage, spell, static_cast<int>(attack_skill));
|
||||
snprintf(buffer, 47, "%d %d %d %d", killer_mob ? killer_mob->GetID() : 0, damage, spell, static_cast<int>(attack_skill));
|
||||
if(parse->EventNPC(EVENT_DEATH, this, oos, buffer, 0) != 0)
|
||||
{
|
||||
if(GetHP() < 0) {
|
||||
@ -2026,15 +2016,15 @@ bool NPC::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes attack
|
||||
return false;
|
||||
}
|
||||
|
||||
if(killerMob && killerMob->IsClient() && (spell != SPELL_UNKNOWN) && damage > 0) {
|
||||
if(killer_mob && killer_mob->IsClient() && (spell != SPELL_UNKNOWN) && damage > 0) {
|
||||
char val1[20]={0};
|
||||
entity_list.MessageClose_StringID(this, false, 100, MT_NonMelee, HIT_NON_MELEE,
|
||||
killerMob->GetCleanName(), GetCleanName(), ConvertArray(damage, val1));
|
||||
killer_mob->GetCleanName(), GetCleanName(), ConvertArray(damage, val1));
|
||||
}
|
||||
} else {
|
||||
|
||||
char buffer[48] = { 0 };
|
||||
snprintf(buffer, 47, "%d %d %d %d", killerMob ? killerMob->GetID() : 0, damage, spell, static_cast<int>(attack_skill));
|
||||
snprintf(buffer, 47, "%d %d %d %d", killer_mob ? killer_mob->GetID() : 0, damage, spell, static_cast<int>(attack_skill));
|
||||
if(parse->EventNPC(EVENT_DEATH, this, nullptr, buffer, 0) != 0)
|
||||
{
|
||||
if(GetHP() < 0) {
|
||||
@ -2072,21 +2062,21 @@ bool NPC::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes attack
|
||||
EQApplicationPacket* app= new EQApplicationPacket(OP_Death,sizeof(Death_Struct));
|
||||
Death_Struct* d = (Death_Struct*)app->pBuffer;
|
||||
d->spawn_id = GetID();
|
||||
d->killer_id = killerMob ? killerMob->GetID() : 0;
|
||||
d->killer_id = killer_mob ? killer_mob->GetID() : 0;
|
||||
d->bindzoneid = 0;
|
||||
d->spell_id = spell == SPELL_UNKNOWN ? 0xffffffff : spell;
|
||||
d->attack_skill = SkillDamageTypes[attack_skill];
|
||||
d->damage = damage;
|
||||
app->priority = 6;
|
||||
entity_list.QueueClients(killerMob, app, false);
|
||||
entity_list.QueueClients(killer_mob, app, false);
|
||||
|
||||
if(respawn2) {
|
||||
respawn2->DeathReset(1);
|
||||
}
|
||||
|
||||
if (killerMob) {
|
||||
if (killer_mob) {
|
||||
if(GetClass() != LDON_TREASURE)
|
||||
hate_list.AddEntToHateList(killerMob, damage);
|
||||
hate_list.AddEntToHateList(killer_mob, damage);
|
||||
}
|
||||
|
||||
safe_delete(app);
|
||||
@ -2148,8 +2138,8 @@ bool NPC::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes attack
|
||||
{
|
||||
if(!IsLdonTreasure && MerchantType == 0) {
|
||||
kr->SplitExp((finalxp), this);
|
||||
if(killerMob && (kr->IsRaidMember(killerMob->GetName()) || kr->IsRaidMember(killerMob->GetUltimateOwner()->GetName())))
|
||||
killerMob->TrySpellOnKill(killed_level,spell);
|
||||
if(killer_mob && (kr->IsRaidMember(killer_mob->GetName()) || kr->IsRaidMember(killer_mob->GetUltimateOwner()->GetName())))
|
||||
killer_mob->TrySpellOnKill(killed_level,spell);
|
||||
}
|
||||
/* Send the EVENT_KILLED_MERIT event for all raid members */
|
||||
for (int i = 0; i < MAX_RAID_MEMBERS; i++) {
|
||||
@ -2193,8 +2183,8 @@ bool NPC::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes attack
|
||||
{
|
||||
if(!IsLdonTreasure && MerchantType == 0) {
|
||||
kg->SplitExp((finalxp), this);
|
||||
if(killerMob && (kg->IsGroupMember(killerMob->GetName()) || kg->IsGroupMember(killerMob->GetUltimateOwner()->GetName())))
|
||||
killerMob->TrySpellOnKill(killed_level,spell);
|
||||
if(killer_mob && (kg->IsGroupMember(killer_mob->GetName()) || kg->IsGroupMember(killer_mob->GetUltimateOwner()->GetName())))
|
||||
killer_mob->TrySpellOnKill(killed_level,spell);
|
||||
}
|
||||
/* Send the EVENT_KILLED_MERIT event and update kill tasks
|
||||
* for all group members */
|
||||
@ -2244,8 +2234,8 @@ bool NPC::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes attack
|
||||
if(!GetOwner() || (GetOwner() && !GetOwner()->IsClient()))
|
||||
{
|
||||
give_exp_client->AddEXP((finalxp), conlevel);
|
||||
if(killerMob && (killerMob->GetID() == give_exp_client->GetID() || killerMob->GetUltimateOwner()->GetID() == give_exp_client->GetID()))
|
||||
killerMob->TrySpellOnKill(killed_level,spell);
|
||||
if(killer_mob && (killer_mob->GetID() == give_exp_client->GetID() || killer_mob->GetUltimateOwner()->GetID() == give_exp_client->GetID()))
|
||||
killer_mob->TrySpellOnKill(killed_level,spell);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2393,20 +2383,30 @@ bool NPC::Death(Mob* killerMob, int32 damage, uint16 spell, SkillUseTypes attack
|
||||
uint16 emoteid = oos->GetEmoteID();
|
||||
if(emoteid != 0)
|
||||
oos->CastToNPC()->DoNPCEmote(KILLEDNPC, emoteid);
|
||||
killerMob->TrySpellOnKill(killed_level, spell);
|
||||
killer_mob->TrySpellOnKill(killed_level, spell);
|
||||
}
|
||||
}
|
||||
|
||||
WipeHateList();
|
||||
p_depop = true;
|
||||
if(killerMob && killerMob->GetTarget() == this) //we can kill things without having them targeted
|
||||
killerMob->SetTarget(nullptr); //via AE effects and such..
|
||||
if(killer_mob && killer_mob->GetTarget() == this) //we can kill things without having them targeted
|
||||
killer_mob->SetTarget(nullptr); //via AE effects and such..
|
||||
|
||||
entity_list.UpdateFindableNPCState(this, true);
|
||||
|
||||
char buffer[48] = { 0 };
|
||||
snprintf(buffer, 47, "%d %d %d %d", killerMob ? killerMob->GetID() : 0, damage, spell, static_cast<int>(attack_skill));
|
||||
snprintf(buffer, 47, "%d %d %d %d", killer_mob ? killer_mob->GetID() : 0, damage, spell, static_cast<int>(attack_skill));
|
||||
parse->EventNPC(EVENT_DEATH_COMPLETE, this, oos, buffer, 0);
|
||||
|
||||
/* Zone controller process EVENT_DEATH_ZONE (Death events) */
|
||||
if (RuleB(Zone, UseZoneController)) {
|
||||
if (entity_list.GetNPCByNPCTypeID(ZONE_CONTROLLER_NPC_ID) && this->GetNPCTypeID() != ZONE_CONTROLLER_NPC_ID){
|
||||
char data_pass[100] = { 0 };
|
||||
snprintf(data_pass, 99, "%d %d %d %d %d", killer_mob ? killer_mob->GetID() : 0, damage, spell, static_cast<int>(attack_skill), this->GetNPCTypeID());
|
||||
parse->EventNPC(EVENT_DEATH_ZONE, entity_list.GetNPCByNPCTypeID(ZONE_CONTROLLER_NPC_ID)->CastToNPC(), nullptr, data_pass, 0);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2693,82 +2693,140 @@ uint8 Mob::GetWeaponDamageBonus(const Item_Struct *weapon, bool offhand)
|
||||
}
|
||||
} else {
|
||||
// 2h damage bonus
|
||||
int damage_bonus = 1 + (level - 28) / 3;
|
||||
if (delay <= 27)
|
||||
return 1 + ((level - 28) / 3);
|
||||
else if (delay < 40)
|
||||
return 1 + ((level - 28) / 3) + ((level - 30) / 5);
|
||||
else if (delay < 43)
|
||||
return 2 + ((level - 28) / 3) + ((level - 30) / 5) + ((delay - 40) / 3);
|
||||
else if (delay < 45)
|
||||
return 3 + ((level - 28) / 3) + ((level - 30) / 5) + ((delay - 40) / 3);
|
||||
else if (delay >= 45)
|
||||
return 4 + ((level - 28) / 3) + ((level - 30) / 5) + ((delay - 40) / 3);
|
||||
return damage_bonus + 1;
|
||||
// Client isn't reflecting what the dev quoted, this matches better
|
||||
if (level > 29) {
|
||||
int level_bonus = (level - 30) / 5 + 1;
|
||||
if (level > 50) {
|
||||
level_bonus++;
|
||||
int level_bonus2 = level - 50;
|
||||
if (level > 67)
|
||||
level_bonus2 += 5;
|
||||
else if (level > 59)
|
||||
level_bonus2 += 4;
|
||||
else if (level > 58)
|
||||
level_bonus2 += 3;
|
||||
else if (level > 56)
|
||||
level_bonus2 += 2;
|
||||
else if (level > 54)
|
||||
level_bonus2++;
|
||||
level_bonus += level_bonus2 * delay / 40;
|
||||
}
|
||||
damage_bonus += level_bonus;
|
||||
}
|
||||
if (delay >= 40) {
|
||||
int delay_bonus = (delay - 40) / 3 + 1;
|
||||
if (delay >= 45)
|
||||
delay_bonus += 2;
|
||||
else if (delay >= 43)
|
||||
delay_bonus++;
|
||||
damage_bonus += delay_bonus;
|
||||
}
|
||||
return damage_bonus;
|
||||
}
|
||||
}
|
||||
|
||||
int Mob::GetMonkHandToHandDamage(void)
|
||||
int Mob::GetHandToHandDamage(void)
|
||||
{
|
||||
// Kaiyodo - Determine a monk's fist damage. Table data from www.monkly-business.com
|
||||
// saved as static array - this should speed this function up considerably
|
||||
static int damage[66] = {
|
||||
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
||||
99, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7,
|
||||
8, 8, 8, 8, 8, 9, 9, 9, 9, 9,10,10,10,10,10,11,11,11,11,11,
|
||||
12,12,12,12,12,13,13,13,13,13,14,14,14,14,14,14,14,14,14,14,
|
||||
14,14,15,15,15,15 };
|
||||
|
||||
// Have a look to see if we have epic fists on
|
||||
|
||||
if (IsClient() && CastToClient()->GetItemIDAt(12) == 10652)
|
||||
return(9);
|
||||
else
|
||||
{
|
||||
int Level = GetLevel();
|
||||
if (Level > 65)
|
||||
return(19);
|
||||
else
|
||||
return damage[Level];
|
||||
if (RuleB(Combat, UseRevampHandToHand)) {
|
||||
// everyone uses this in the revamp!
|
||||
int skill = GetSkill(SkillHandtoHand);
|
||||
int epic = 0;
|
||||
if (IsClient() && CastToClient()->GetItemIDAt(12) == 10652 && GetLevel() > 46)
|
||||
epic = 280;
|
||||
if (epic > skill)
|
||||
skill = epic;
|
||||
return skill / 15 + 3;
|
||||
}
|
||||
|
||||
static uint8 mnk_dmg[] = {99,
|
||||
4, 4, 4, 4, 5, 5, 5, 5, 5, 6, // 1-10
|
||||
6, 6, 6, 6, 7, 7, 7, 7, 7, 8, // 11-20
|
||||
8, 8, 8, 8, 9, 9, 9, 9, 9, 10, // 21-30
|
||||
10, 10, 10, 10, 11, 11, 11, 11, 11, 12, // 31-40
|
||||
12, 12, 12, 12, 13, 13, 13, 13, 13, 14, // 41-50
|
||||
14, 14, 14, 14, 14, 14, 14, 14, 14, 14, // 51-60
|
||||
14, 14}; // 61-62
|
||||
static uint8 bst_dmg[] = {99,
|
||||
4, 4, 4, 4, 4, 5, 5, 5, 5, 5, // 1-10
|
||||
5, 6, 6, 6, 6, 6, 6, 7, 7, 7, // 11-20
|
||||
7, 7, 7, 8, 8, 8, 8, 8, 8, 9, // 21-30
|
||||
9, 9, 9, 9, 9, 10, 10, 10, 10, 10, // 31-40
|
||||
10, 11, 11, 11, 11, 11, 11, 12, 12}; // 41-49
|
||||
if (GetClass() == MONK) {
|
||||
if (IsClient() && CastToClient()->GetItemIDAt(12) == 10652 && GetLevel() > 50)
|
||||
return 9;
|
||||
if (level > 62)
|
||||
return 15;
|
||||
return mnk_dmg[level];
|
||||
} else if (GetClass() == BEASTLORD) {
|
||||
if (level > 49)
|
||||
return 13;
|
||||
return bst_dmg[level];
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
|
||||
int Mob::GetMonkHandToHandDelay(void)
|
||||
int Mob::GetHandToHandDelay(void)
|
||||
{
|
||||
// Kaiyodo - Determine a monk's fist delay. Table data from www.monkly-business.com
|
||||
// saved as static array - this should speed this function up considerably
|
||||
static int delayshuman[66] = {
|
||||
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
||||
99,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,
|
||||
36,36,36,36,36,35,35,35,35,35,34,34,34,34,34,33,33,33,33,33,
|
||||
32,32,32,32,32,31,31,31,31,31,30,30,30,29,29,29,28,28,28,27,
|
||||
26,24,22,20,20,20 };
|
||||
static int delaysiksar[66] = {
|
||||
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
||||
99,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,36,
|
||||
36,36,36,36,36,36,36,36,36,36,35,35,35,35,35,34,34,34,34,34,
|
||||
33,33,33,33,33,32,32,32,32,32,31,31,31,30,30,30,29,29,29,28,
|
||||
27,24,22,20,20,20 };
|
||||
|
||||
// Have a look to see if we have epic fists on
|
||||
if (IsClient() && CastToClient()->GetItemIDAt(12) == 10652)
|
||||
return(16);
|
||||
else
|
||||
{
|
||||
int Level = GetLevel();
|
||||
if (GetRace() == HUMAN)
|
||||
{
|
||||
if (Level > 65)
|
||||
return(24);
|
||||
else
|
||||
return delayshuman[Level];
|
||||
}
|
||||
else //heko: iksar table
|
||||
{
|
||||
if (Level > 65)
|
||||
return(25);
|
||||
else
|
||||
return delaysiksar[Level];
|
||||
}
|
||||
if (RuleB(Combat, UseRevampHandToHand)) {
|
||||
// everyone uses this in the revamp!
|
||||
int skill = GetSkill(SkillHandtoHand);
|
||||
int epic = 0;
|
||||
int iksar = 0;
|
||||
if (IsClient() && CastToClient()->GetItemIDAt(12) == 10652 && GetLevel() > 46)
|
||||
epic = 280;
|
||||
else if (GetRace() == IKSAR)
|
||||
iksar = 1;
|
||||
if (epic > skill)
|
||||
skill = epic;
|
||||
return iksar - skill / 21 + 38;
|
||||
}
|
||||
|
||||
int delay = 35;
|
||||
static uint8 mnk_hum_delay[] = {99,
|
||||
35, 35, 35, 35, 35, 35, 35, 35, 35, 35, // 1-10
|
||||
35, 35, 35, 35, 35, 35, 35, 35, 35, 35, // 11-20
|
||||
35, 35, 35, 35, 35, 35, 35, 34, 34, 34, // 21-30
|
||||
34, 33, 33, 33, 33, 32, 32, 32, 32, 31, // 31-40
|
||||
31, 31, 31, 30, 30, 30, 30, 29, 29, 29, // 41-50
|
||||
29, 28, 28, 28, 28, 27, 27, 27, 27, 26, // 51-60
|
||||
24, 22}; // 61-62
|
||||
static uint8 mnk_iks_delay[] = {99,
|
||||
35, 35, 35, 35, 35, 35, 35, 35, 35, 35, // 1-10
|
||||
35, 35, 35, 35, 35, 35, 35, 35, 35, 35, // 11-20
|
||||
35, 35, 35, 35, 35, 35, 35, 35, 35, 34, // 21-30
|
||||
34, 34, 34, 34, 34, 33, 33, 33, 33, 33, // 31-40
|
||||
33, 32, 32, 32, 32, 32, 32, 31, 31, 31, // 41-50
|
||||
31, 31, 31, 30, 30, 30, 30, 30, 30, 29, // 51-60
|
||||
25, 23}; // 61-62
|
||||
static uint8 bst_delay[] = {99,
|
||||
35, 35, 35, 35, 35, 35, 35, 35, 35, 35, // 1-10
|
||||
35, 35, 35, 35, 35, 35, 35, 35, 35, 35, // 11-20
|
||||
35, 35, 35, 35, 35, 35, 35, 35, 34, 34, // 21-30
|
||||
34, 34, 34, 33, 33, 33, 33, 33, 32, 32, // 31-40
|
||||
32, 32, 32, 31, 31, 31, 31, 31, 30, 30, // 41-50
|
||||
30, 30, 30, 29, 29, 29, 29, 29, 28, 28, // 51-60
|
||||
28, 28, 28, 27, 27, 27, 27, 27, 26, 26, // 61-70
|
||||
26, 26, 26}; // 71-73
|
||||
|
||||
if (GetClass() == MONK) {
|
||||
// Have a look to see if we have epic fists on
|
||||
if (IsClient() && CastToClient()->GetItemIDAt(12) == 10652 && GetLevel() > 50)
|
||||
return 16;
|
||||
int level = GetLevel();
|
||||
if (level > 62)
|
||||
return GetRace() == IKSAR ? 21 : 20;
|
||||
return GetRace() == IKSAR ? mnk_iks_delay[level] : mnk_hum_delay[level];
|
||||
} else if (GetClass() == BEASTLORD) {
|
||||
int level = GetLevel();
|
||||
if (level > 73)
|
||||
return 25;
|
||||
return bst_delay[level];
|
||||
}
|
||||
return 35;
|
||||
}
|
||||
|
||||
int32 Mob::ReduceDamage(int32 damage)
|
||||
@ -4617,28 +4675,27 @@ void Client::SetAttackTimer()
|
||||
|
||||
int hhe = itembonuses.HundredHands + spellbonuses.HundredHands;
|
||||
int speed = 0;
|
||||
int delay = 36;
|
||||
float quiver_haste = 0.0f;
|
||||
int delay = 3500;
|
||||
|
||||
//if we have no weapon..
|
||||
if (ItemToUse == nullptr) {
|
||||
//above checks ensure ranged weapons do not fall into here
|
||||
// Work out if we're a monk
|
||||
if (GetClass() == MONK || GetClass() == BEASTLORD)
|
||||
delay = GetMonkHandToHandDelay();
|
||||
} else {
|
||||
//we have a weapon, use its delay
|
||||
delay = ItemToUse->Delay;
|
||||
if (ItemToUse->ItemType == ItemTypeBow || ItemToUse->ItemType == ItemTypeLargeThrowing)
|
||||
quiver_haste = GetQuiverHaste();
|
||||
}
|
||||
if (RuleB(Spells, Jun182014HundredHandsRevamp))
|
||||
speed = static_cast<int>(((delay / haste_mod) + ((hhe / 1000.0f) * (delay / haste_mod))) * 100);
|
||||
if (ItemToUse == nullptr)
|
||||
delay = 100 * GetHandToHandDelay();
|
||||
else
|
||||
speed = static_cast<int>(((delay / haste_mod) + ((hhe / 100.0f) * delay)) * 100);
|
||||
// this is probably wrong
|
||||
if (quiver_haste > 0)
|
||||
speed *= quiver_haste;
|
||||
//we have a weapon, use its delay
|
||||
delay = 100 * ItemToUse->Delay;
|
||||
|
||||
speed = delay / haste_mod;
|
||||
|
||||
if (ItemToUse && ItemToUse->ItemType == ItemTypeBow) {
|
||||
// Live actually had a bug here where they would return the non-modified attack speed
|
||||
// rather than the cap ...
|
||||
speed = std::max(speed - GetQuiverHaste(speed), RuleI(Combat, QuiverHasteCap));
|
||||
} else {
|
||||
if (RuleB(Spells, Jun182014HundredHandsRevamp))
|
||||
speed = static_cast<int>(speed + ((hhe / 1000.0f) * speed));
|
||||
else
|
||||
speed = static_cast<int>(speed + ((hhe / 100.0f) * delay));
|
||||
}
|
||||
TimerToUse->SetAtTrigger(std::max(RuleI(Combat, MinHastedDelay), speed), true, true);
|
||||
}
|
||||
}
|
||||
|
||||
62
zone/bot.cpp
62
zone/bot.cpp
@ -6236,31 +6236,44 @@ float Bot::GetProcChances(float ProcBonus, uint16 hand) {
|
||||
return ProcChance;
|
||||
}
|
||||
|
||||
int Bot::GetMonkHandToHandDamage(void) {
|
||||
static int damage[66] = {
|
||||
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
||||
99, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7,
|
||||
8, 8, 8, 8, 8, 9, 9, 9, 9, 9,10,10,10,10,10,11,11,11,11,11,
|
||||
12,12,12,12,12,13,13,13,13,13,14,14,14,14,14,14,14,14,14,14,
|
||||
14,14,15,15,15,15 };
|
||||
int Bot::GetHandToHandDamage(void) {
|
||||
if (RuleB(Combat, UseRevampHandToHand)) {
|
||||
// everyone uses this in the revamp!
|
||||
int skill = GetSkill(SkillHandtoHand);
|
||||
int epic = 0;
|
||||
if (CastToNPC()->GetEquipment(MaterialHands) == 10652 && GetLevel() > 46)
|
||||
epic = 280;
|
||||
if (epic > skill)
|
||||
skill = epic;
|
||||
return skill / 15 + 3;
|
||||
}
|
||||
|
||||
uint32 botWeaponId = INVALID_ID;
|
||||
botWeaponId = CastToNPC()->GetEquipment(MaterialHands);
|
||||
if(botWeaponId == 10652)
|
||||
static uint8 mnk_dmg[] = {99,
|
||||
4, 4, 4, 4, 5, 5, 5, 5, 5, 6, // 1-10
|
||||
6, 6, 6, 6, 7, 7, 7, 7, 7, 8, // 11-20
|
||||
8, 8, 8, 8, 9, 9, 9, 9, 9, 10, // 21-30
|
||||
10, 10, 10, 10, 11, 11, 11, 11, 11, 12, // 31-40
|
||||
12, 12, 12, 12, 13, 13, 13, 13, 13, 14, // 41-50
|
||||
14, 14, 14, 14, 14, 14, 14, 14, 14, 14, // 51-60
|
||||
14, 14}; // 61-62
|
||||
static uint8 bst_dmg[] = {99,
|
||||
4, 4, 4, 4, 4, 5, 5, 5, 5, 5, // 1-10
|
||||
5, 6, 6, 6, 6, 6, 6, 7, 7, 7, // 11-20
|
||||
7, 7, 7, 8, 8, 8, 8, 8, 8, 9, // 21-30
|
||||
9, 9, 9, 9, 9, 10, 10, 10, 10, 10, // 31-40
|
||||
10, 11, 11, 11, 11, 11, 11, 12, 12}; // 41-49
|
||||
if (GetClass() == MONK) {
|
||||
if (CastToNPC()->GetEquipment(MaterialHands) == 10652 && GetLevel() > 50)
|
||||
return 9;
|
||||
else {
|
||||
int Level = GetLevel();
|
||||
if(Level > 65)
|
||||
return 19;
|
||||
else
|
||||
return damage[Level];
|
||||
}
|
||||
|
||||
int Level = GetLevel();
|
||||
if (Level > 65)
|
||||
return 19;
|
||||
else
|
||||
return damage[Level];
|
||||
if (level > 62)
|
||||
return 15;
|
||||
return mnk_dmg[level];
|
||||
} else if (GetClass() == BEASTLORD) {
|
||||
if (level > 49)
|
||||
return 13;
|
||||
return bst_dmg[level];
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
|
||||
bool Bot::TryFinishingBlow(Mob *defender, SkillUseTypes skillinuse) {
|
||||
@ -7012,8 +7025,7 @@ void Bot::SetAttackTimer() {
|
||||
int speed = 0;
|
||||
int delay = 36;
|
||||
if (ItemToUse == nullptr) {
|
||||
if ((GetClass() == MONK) || (GetClass() == BEASTLORD))
|
||||
delay = GetMonkHandToHandDelay();
|
||||
delay = GetHandToHandDelay();
|
||||
} else {
|
||||
delay = ItemToUse->Delay;
|
||||
}
|
||||
|
||||
@ -171,7 +171,7 @@ public:
|
||||
uint16 BotGetSpellType(int spellslot) { return AIspells[spellslot].type; }
|
||||
uint16 BotGetSpellPriority(int spellslot) { return AIspells[spellslot].priority; }
|
||||
virtual float GetProcChances(float ProcBonus, uint16 hand);
|
||||
virtual int GetMonkHandToHandDamage(void);
|
||||
virtual int GetHandToHandDamage(void);
|
||||
virtual bool TryFinishingBlow(Mob *defender, SkillUseTypes skillinuse);
|
||||
virtual void DoRiposte(Mob* defender);
|
||||
inline virtual int32 GetATK() const { return ATK + itembonuses.ATK + spellbonuses.ATK + ((GetSTR() + GetSkill(SkillOffense)) * 9 / 10); }
|
||||
|
||||
@ -6803,7 +6803,8 @@ void Client::SendStatsWindow(Client* client, bool use_window)
|
||||
/* AC */ indP << "<c \"#CCFF00\">AC: " << CalcAC() << "</c><br>" <<
|
||||
/* AC2 */ indP << "- Mit: " << GetACMit() << " | Avoid: " << GetACAvoid() << " | Spell: " << spellbonuses.AC << " | Shield: " << shield_ac << "<br>" <<
|
||||
/* Haste */ indP << "<c \"#CCFF00\">Haste: " << GetHaste() << "</c><br>" <<
|
||||
/* Haste2 */ indP << " - Item: " << itembonuses.haste << " + Spell: " << (spellbonuses.haste + spellbonuses.hastetype2) << " (Cap: " << RuleI(Character, HasteCap) << ") | Over: " << (spellbonuses.hastetype3 + ExtraHaste) << "<br><br>" <<
|
||||
/* Haste2 */ indP << " - Item: " << itembonuses.haste << " + Spell: " << (spellbonuses.haste + spellbonuses.hastetype2) << " (Cap: " << RuleI(Character, HasteCap) << ") | Over: " << (spellbonuses.hastetype3 + ExtraHaste) << "<br>" <<
|
||||
/* RunSpeed*/ indP << "<c \"#CCFF00\">Runspeed: " << GetRunspeed() << "</c><br>" <<
|
||||
/* RegenLbl */ indL << indS << "Regen<br>" << indS << indP << indP << " Base | Items (Cap) " << indP << " | Spell | A.A.s | Total<br>" <<
|
||||
/* Regen */ regen_string << "<br>" <<
|
||||
/* Stats */ stat_field << "<br><br>" <<
|
||||
@ -8355,21 +8356,19 @@ void Client::ShowNumHits()
|
||||
return;
|
||||
}
|
||||
|
||||
float Client::GetQuiverHaste()
|
||||
int Client::GetQuiverHaste(int delay)
|
||||
{
|
||||
float quiver_haste = 0;
|
||||
const ItemInst *pi = nullptr;
|
||||
for (int r = EmuConstants::GENERAL_BEGIN; r <= EmuConstants::GENERAL_END; r++) {
|
||||
const ItemInst *pi = GetInv().GetItem(r);
|
||||
if (!pi)
|
||||
continue;
|
||||
if (pi->IsType(ItemClassContainer) && pi->GetItem()->BagType == BagTypeQuiver) {
|
||||
float temp_wr = (pi->GetItem()->BagWR / RuleI(Combat, QuiverWRHasteDiv));
|
||||
quiver_haste = std::max(temp_wr, quiver_haste);
|
||||
}
|
||||
pi = GetInv().GetItem(r);
|
||||
if (pi && pi->IsType(ItemClassContainer) && pi->GetItem()->BagType == BagTypeQuiver &&
|
||||
pi->GetItem()->BagWR > 0)
|
||||
break;
|
||||
if (r == EmuConstants::GENERAL_END)
|
||||
// we will get here if we don't find a valid quiver
|
||||
return 0;
|
||||
}
|
||||
if (quiver_haste > 0)
|
||||
quiver_haste = 1.0f / (1.0f + static_cast<float>(quiver_haste) / 100.0f);
|
||||
return quiver_haste;
|
||||
return (pi->GetItem()->BagWR * 0.0025f * delay) + 1;
|
||||
}
|
||||
|
||||
void Client::SendColoredText(uint32 color, std::string message)
|
||||
|
||||
@ -226,7 +226,7 @@ public:
|
||||
virtual inline bool IsBerserk() { return berserk; }
|
||||
virtual int32 GetMeleeMitDmg(Mob *attacker, int32 damage, int32 minhit, float mit_rating, float atk_rating);
|
||||
virtual void SetAttackTimer();
|
||||
float GetQuiverHaste();
|
||||
int GetQuiverHaste(int delay);
|
||||
void DoAttackRounds(Mob *target, int hand, bool IsFromSpell = false);
|
||||
|
||||
void AI_Init();
|
||||
|
||||
@ -58,8 +58,8 @@ int32 Client::GetMaxResist() const
|
||||
{
|
||||
int level = GetLevel();
|
||||
int32 base = 500;
|
||||
if (level > 60) {
|
||||
base += ((level - 60) * 5);
|
||||
if (level > 65) {
|
||||
base += ((level - 65) * 5);
|
||||
}
|
||||
return base;
|
||||
}
|
||||
|
||||
@ -194,6 +194,7 @@ int command_init(void)
|
||||
command_add("enablerecipe", "[recipe_id] - Enables a recipe using the recipe id.", 80, command_enablerecipe) ||
|
||||
command_add("equipitem", "[slotid(0-21)] - Equip the item on your cursor into the specified slot", 50, command_equipitem) ||
|
||||
command_add("face", "- Change the face of your target", 80, command_face) ||
|
||||
command_add("findaliases", "[search term]- Searches for available command aliases, by alias or command", 0, command_findaliases) ||
|
||||
command_add("findnpctype", "[search criteria] - Search database NPC types", 100, command_findnpctype) ||
|
||||
command_add("findspell", "[searchstring] - Search for a spell", 50, command_findspell) ||
|
||||
command_add("findzone", "[search criteria] - Search database zones", 100, command_findzone) ||
|
||||
@ -4945,6 +4946,38 @@ void command_face(Client *c, const Seperator *sep)
|
||||
}
|
||||
}
|
||||
|
||||
void command_findaliases(Client *c, const Seperator *sep)
|
||||
{
|
||||
if (!sep->arg[1][0]) {
|
||||
c->Message(0, "Usage: #findaliases [alias | command]");
|
||||
return;
|
||||
}
|
||||
|
||||
std::map<std::string, std::string>::iterator find_iter = commandaliases.find(sep->arg[1]);
|
||||
if (find_iter == commandaliases.end()) {
|
||||
c->Message(15, "No commands or aliases match '%s'", sep->arg[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
std::map<std::string, CommandRecord *>::iterator command_iter = commandlist.find(find_iter->second);
|
||||
if (find_iter->second.empty() || command_iter == commandlist.end()) {
|
||||
c->Message(0, "An unknown condition occurred...");
|
||||
return;
|
||||
}
|
||||
|
||||
c->Message(0, "Available command aliases for '%s':", command_iter->first.c_str());
|
||||
|
||||
int commandaliasesshown = 0;
|
||||
for (std::map<std::string, std::string>::iterator alias_iter = commandaliases.begin(); alias_iter != commandaliases.end(); ++alias_iter) {
|
||||
if (strcasecmp(find_iter->second.c_str(), alias_iter->second.c_str()) || c->Admin() < command_iter->second->access)
|
||||
continue;
|
||||
|
||||
c->Message(0, "%c%s", COMMAND_CHAR, alias_iter->first.c_str());
|
||||
++commandaliasesshown;
|
||||
}
|
||||
c->Message(0, "%d command alias%s listed.", commandaliasesshown, commandaliasesshown != 1 ? "es" : "");
|
||||
}
|
||||
|
||||
void command_details(Client *c, const Seperator *sep)
|
||||
{
|
||||
Mob *target=c->GetTarget();
|
||||
|
||||
@ -94,6 +94,7 @@ void command_emoteview(Client* c, const Seperator *sep);
|
||||
void command_enablerecipe(Client *c, const Seperator *sep);
|
||||
void command_equipitem(Client *c, const Seperator *sep);
|
||||
void command_face(Client *c, const Seperator *sep);
|
||||
void command_findaliases(Client *c, const Seperator *sep);
|
||||
void command_findnpctype(Client *c, const Seperator *sep);
|
||||
void command_findspell(Client *c, const Seperator *sep);
|
||||
void command_findzone(Client *c, const Seperator *sep);
|
||||
|
||||
@ -114,7 +114,9 @@ const char *QuestEventSubroutines[_LargestEventID] = {
|
||||
"EVENT_RESPAWN",
|
||||
"EVENT_DEATH_COMPLETE",
|
||||
"EVENT_UNHANDLED_OPCODE",
|
||||
"EVENT_TICK"
|
||||
"EVENT_TICK",
|
||||
"EVENT_SPAWN_ZONE",
|
||||
"EVENT_DEATH_ZONE",
|
||||
};
|
||||
|
||||
PerlembParser::PerlembParser() : perl(nullptr) {
|
||||
@ -1424,6 +1426,21 @@ void PerlembParser::ExportEventVariables(std::string &package_name, QuestEventID
|
||||
ExportVar(package_name.c_str(), "slotid", extradata);
|
||||
break;
|
||||
}
|
||||
case EVENT_SPAWN_ZONE: {
|
||||
Seperator sep(data);
|
||||
ExportVar(package_name.c_str(), "spawned_entity_id", sep.arg[0]);
|
||||
ExportVar(package_name.c_str(), "spawned_npc_id", sep.arg[1]);
|
||||
break;
|
||||
}
|
||||
case EVENT_DEATH_ZONE: {
|
||||
Seperator sep(data);
|
||||
ExportVar(package_name.c_str(), "killer_id", sep.arg[0]);
|
||||
ExportVar(package_name.c_str(), "killer_damage", sep.arg[1]);
|
||||
ExportVar(package_name.c_str(), "killer_spell", sep.arg[2]);
|
||||
ExportVar(package_name.c_str(), "killer_skill", sep.arg[3]);
|
||||
ExportVar(package_name.c_str(), "killed_npc_id", sep.arg[4]);
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
break;
|
||||
|
||||
@ -2919,6 +2919,29 @@ XS(XS__UpdateInstanceTimer) {
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
|
||||
XS(XS__GetInstanceTimer);
|
||||
XS(XS__GetInstanceTimer) {
|
||||
dXSARGS;
|
||||
if (items != 0)
|
||||
Perl_croak(aTHX_ "Usage: GetInstanceTimer()");
|
||||
|
||||
uint32 timer = quest_manager.GetInstanceTimer();
|
||||
|
||||
XSRETURN_UV(timer);
|
||||
}
|
||||
|
||||
XS(XS__GetInstanceTimerByID);
|
||||
XS(XS__GetInstanceTimerByID) {
|
||||
dXSARGS;
|
||||
if (items != 1)
|
||||
Perl_croak(aTHX_ "Usage: GetInstanceTimerByID(instance_id)");
|
||||
|
||||
uint16 instance_id = (uint16)SvUV(ST(0));
|
||||
uint32 timer = quest_manager.GetInstanceTimerByID(instance_id);
|
||||
|
||||
XSRETURN_UV(timer);
|
||||
}
|
||||
|
||||
XS(XS__GetInstanceID);
|
||||
XS(XS__GetInstanceID) {
|
||||
dXSARGS;
|
||||
@ -3614,6 +3637,19 @@ XS(XS__debug)
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
|
||||
XS(XS__UpdateZoneHeader);
|
||||
XS(XS__UpdateZoneHeader) {
|
||||
dXSARGS;
|
||||
if (items != 2)
|
||||
Perl_croak(aTHX_ "Usage: UpdateZoneHeader(type, value)");
|
||||
|
||||
std::string type = (std::string)SvPV_nolen(ST(0));
|
||||
std::string value = (std::string)SvPV_nolen(ST(1));
|
||||
quest_manager.UpdateZoneHeader(type, value);
|
||||
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
This is the callback perl will look for to setup the
|
||||
@ -3650,6 +3686,8 @@ EXTERN_C XS(boot_quest)
|
||||
newXS(strcpy(buf, "CreateInstance"), XS__CreateInstance, file);
|
||||
newXS(strcpy(buf, "DestroyInstance"), XS__DestroyInstance, file);
|
||||
newXS(strcpy(buf, "UpdateInstanceTimer"), XS__UpdateInstanceTimer, file);
|
||||
newXS(strcpy(buf, "GetInstanceTimer"), XS__GetInstanceTimer, file);
|
||||
newXS(strcpy(buf, "GetInstanceTimerByID"), XS__GetInstanceTimerByID, file);
|
||||
newXS(strcpy(buf, "FlagInstanceByGroupLeader"), XS__FlagInstanceByGroupLeader, file);
|
||||
newXS(strcpy(buf, "FlagInstanceByRaidLeader"), XS__FlagInstanceByRaidLeader, file);
|
||||
newXS(strcpy(buf, "FlyMode"), XS__FlyMode, file);
|
||||
@ -3841,6 +3879,7 @@ EXTERN_C XS(boot_quest)
|
||||
newXS(strcpy(buf, "untraindiscs"), XS__untraindiscs, file);
|
||||
newXS(strcpy(buf, "updatespawntimer"), XS__UpdateSpawnTimer, file);
|
||||
newXS(strcpy(buf, "updatetaskactivity"), XS__updatetaskactivity, file);
|
||||
newXS(strcpy(buf, "UpdateZoneHeader"), XS__UpdateZoneHeader, file);
|
||||
newXS(strcpy(buf, "varlink"), XS__varlink, file);
|
||||
newXS(strcpy(buf, "voicetell"), XS__voicetell, file);
|
||||
newXS(strcpy(buf, "we"), XS__we, file);
|
||||
|
||||
@ -641,8 +641,18 @@ void EntityList::AddNPC(NPC *npc, bool SendSpawnPacket, bool dontqueue)
|
||||
{
|
||||
npc->SetID(GetFreeID());
|
||||
npc->SetMerchantProbability((uint8) zone->random.Int(0, 99));
|
||||
|
||||
parse->EventNPC(EVENT_SPAWN, npc, nullptr, "", 0);
|
||||
|
||||
/* Zone controller process EVENT_SPAWN_ZONE */
|
||||
if (RuleB(Zone, UseZoneController)) {
|
||||
if (entity_list.GetNPCByNPCTypeID(ZONE_CONTROLLER_NPC_ID) && npc->GetNPCTypeID() != ZONE_CONTROLLER_NPC_ID){
|
||||
char data_pass[100] = { 0 };
|
||||
snprintf(data_pass, 99, "%d %d", npc->GetID(), npc->GetNPCTypeID());
|
||||
parse->EventNPC(EVENT_SPAWN_ZONE, entity_list.GetNPCByNPCTypeID(ZONE_CONTROLLER_NPC_ID)->CastToNPC(), nullptr, data_pass, 0);
|
||||
}
|
||||
}
|
||||
|
||||
uint16 emoteid = npc->GetEmoteID();
|
||||
if (emoteid != 0)
|
||||
npc->DoNPCEmote(ONSPAWN, emoteid);
|
||||
|
||||
@ -83,7 +83,8 @@ typedef enum {
|
||||
EVENT_DEATH_COMPLETE,
|
||||
EVENT_UNHANDLED_OPCODE,
|
||||
EVENT_TICK,
|
||||
|
||||
EVENT_SPAWN_ZONE,
|
||||
EVENT_DEATH_ZONE,
|
||||
_LargestEventID
|
||||
} QuestEventID;
|
||||
|
||||
|
||||
@ -808,6 +808,14 @@ void lua_update_instance_timer(uint16 instance_id, uint32 new_duration) {
|
||||
quest_manager.UpdateInstanceTimer(instance_id, new_duration);
|
||||
}
|
||||
|
||||
uint32 lua_get_instance_timer() {
|
||||
return quest_manager.GetInstanceTimer();
|
||||
}
|
||||
|
||||
uint32 lua_get_instance_timer_by_id(uint16 instance_id) {
|
||||
return quest_manager.GetInstanceTimerByID(instance_id);
|
||||
}
|
||||
|
||||
int lua_get_instance_id(const char *zone, uint32 version) {
|
||||
return quest_manager.GetInstanceID(zone, version);
|
||||
}
|
||||
@ -1296,6 +1304,10 @@ void lua_debug(std::string message, int level) {
|
||||
Log.Out(static_cast<Logs::DebugLevel>(level), Logs::QuestDebug, message);
|
||||
}
|
||||
|
||||
void lua_update_zone_header(std::string type, std::string value) {
|
||||
quest_manager.UpdateZoneHeader(type, value);
|
||||
}
|
||||
|
||||
#define LuaCreateNPCParse(name, c_type, default_value) do { \
|
||||
cur = table[#name]; \
|
||||
if(luabind::type(cur) != LUA_TNIL) { \
|
||||
@ -1719,7 +1731,9 @@ luabind::scope lua_register_events() {
|
||||
luabind::value("leave_area", static_cast<int>(EVENT_LEAVE_AREA)),
|
||||
luabind::value("death_complete", static_cast<int>(EVENT_DEATH_COMPLETE)),
|
||||
luabind::value("unhandled_opcode", static_cast<int>(EVENT_UNHANDLED_OPCODE)),
|
||||
luabind::value("tick", static_cast<int>(EVENT_TICK))
|
||||
luabind::value("tick", static_cast<int>(EVENT_TICK)),
|
||||
luabind::value("spawn_zone", static_cast<int>(EVENT_SPAWN_ZONE)),
|
||||
luabind::value("death_zone", static_cast<int>(EVENT_DEATH_ZONE))
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@ -1023,14 +1023,14 @@ int Lua_Mob::GetHaste() {
|
||||
return self->GetHaste();
|
||||
}
|
||||
|
||||
int Lua_Mob::GetMonkHandToHandDamage() {
|
||||
int Lua_Mob::GetHandToHandDamage() {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->GetMonkHandToHandDamage();
|
||||
return self->GetHandToHandDamage();
|
||||
}
|
||||
|
||||
int Lua_Mob::GetMonkHandToHandDelay() {
|
||||
int Lua_Mob::GetHandToHandDelay() {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->GetMonkHandToHandDelay();
|
||||
return self->GetHandToHandDelay();
|
||||
}
|
||||
|
||||
void Lua_Mob::Mesmerize() {
|
||||
@ -2165,8 +2165,8 @@ luabind::scope lua_register_mob() {
|
||||
.def("GetInvul", (bool(Lua_Mob::*)(void))&Lua_Mob::GetInvul)
|
||||
.def("SetExtraHaste", (void(Lua_Mob::*)(int))&Lua_Mob::SetExtraHaste)
|
||||
.def("GetHaste", (int(Lua_Mob::*)(void))&Lua_Mob::GetHaste)
|
||||
.def("GetMonkHandToHandDamage", (int(Lua_Mob::*)(void))&Lua_Mob::GetMonkHandToHandDamage)
|
||||
.def("GetMonkHandToHandDelay", (int(Lua_Mob::*)(void))&Lua_Mob::GetMonkHandToHandDelay)
|
||||
.def("GetHandToHandDamage", (int(Lua_Mob::*)(void))&Lua_Mob::GetHandToHandDamage)
|
||||
.def("GetHandToHandDelay", (int(Lua_Mob::*)(void))&Lua_Mob::GetHandToHandDelay)
|
||||
.def("Mesmerize", (void(Lua_Mob::*)(void))&Lua_Mob::Mesmerize)
|
||||
.def("IsMezzed", (bool(Lua_Mob::*)(void))&Lua_Mob::IsMezzed)
|
||||
.def("IsEnraged", (bool(Lua_Mob::*)(void))&Lua_Mob::IsEnraged)
|
||||
@ -2303,7 +2303,7 @@ luabind::scope lua_register_mob() {
|
||||
.def("BuffFadeBySlot", (void(Lua_Mob::*)(int,bool))&Lua_Mob::BuffFadeBySlot)
|
||||
.def("CanBuffStack", (int(Lua_Mob::*)(int,int))&Lua_Mob::CanBuffStack)
|
||||
.def("CanBuffStack", (int(Lua_Mob::*)(int,int,bool))&Lua_Mob::CanBuffStack)
|
||||
.def("SetPseudoRoot", (void(Lua_Mob::*)(void))&Lua_Mob::SetPseudoRoot)
|
||||
.def("SetPseudoRoot", (void(Lua_Mob::*)(bool))&Lua_Mob::SetPseudoRoot)
|
||||
.def("SeeInvisible", (uint8(Lua_Mob::*)(void))&Lua_Mob::SeeInvisible)
|
||||
.def("SeeInvisibleUndead", (bool(Lua_Mob::*)(void))&Lua_Mob::SeeInvisibleUndead)
|
||||
.def("SeeHide", (bool(Lua_Mob::*)(void))&Lua_Mob::SeeHide)
|
||||
|
||||
@ -217,8 +217,8 @@ public:
|
||||
bool GetInvul();
|
||||
void SetExtraHaste(int haste);
|
||||
int GetHaste();
|
||||
int GetMonkHandToHandDamage();
|
||||
int GetMonkHandToHandDelay();
|
||||
int GetHandToHandDamage();
|
||||
int GetHandToHandDelay();
|
||||
void Mesmerize();
|
||||
bool IsMezzed();
|
||||
bool IsEnraged();
|
||||
|
||||
@ -428,6 +428,11 @@ float Lua_NPC::GetAttackSpeed() {
|
||||
return self->GetAttackSpeed();
|
||||
}
|
||||
|
||||
int Lua_NPC::GetAttackDelay() {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->GetAttackDelay();
|
||||
}
|
||||
|
||||
int Lua_NPC::GetAccuracyRating() {
|
||||
Lua_Safe_Call_Int();
|
||||
return self->GetAccuracyRating();
|
||||
@ -550,6 +555,7 @@ luabind::scope lua_register_npc() {
|
||||
.def("GetSpellFocusHeal", (void(Lua_NPC::*)(int))&Lua_NPC::GetSpellFocusHeal)
|
||||
.def("GetSlowMitigation", (int(Lua_NPC::*)(void))&Lua_NPC::GetSlowMitigation)
|
||||
.def("GetAttackSpeed", (float(Lua_NPC::*)(void))&Lua_NPC::GetAttackSpeed)
|
||||
.def("GetAttackDelay", (int(Lua_NPC::*)(void))&Lua_NPC::GetAttackDelay)
|
||||
.def("GetAccuracyRating", (int(Lua_NPC::*)(void))&Lua_NPC::GetAccuracyRating)
|
||||
.def("GetSpawnKillCount", (int(Lua_NPC::*)(void))&Lua_NPC::GetSpawnKillCount)
|
||||
.def("GetScore", (int(Lua_NPC::*)(void))&Lua_NPC::GetScore)
|
||||
|
||||
@ -111,6 +111,7 @@ public:
|
||||
int GetSpellFocusHeal();
|
||||
float GetSlowMitigation();
|
||||
float GetAttackSpeed();
|
||||
int GetAttackDelay();
|
||||
int GetAccuracyRating();
|
||||
int GetSpawnKillCount();
|
||||
int GetScore();
|
||||
|
||||
@ -117,7 +117,9 @@ const char *LuaEvents[_LargestEventID] = {
|
||||
"event_respawn",
|
||||
"event_death_complete",
|
||||
"event_unhandled_opcode",
|
||||
"event_tick"
|
||||
"event_tick",
|
||||
"event_spawn_zone",
|
||||
"event_death_zone"
|
||||
};
|
||||
|
||||
extern Zone *zone;
|
||||
|
||||
@ -756,7 +756,7 @@ public:
|
||||
|
||||
uint8 GetWeaponDamageBonus(const Item_Struct* weapon, bool offhand = false);
|
||||
uint16 GetDamageTable(SkillUseTypes skillinuse);
|
||||
virtual int GetMonkHandToHandDamage(void);
|
||||
virtual int GetHandToHandDamage(void);
|
||||
|
||||
bool CanThisClassDoubleAttack(void) const;
|
||||
bool CanThisClassTripleAttack() const;
|
||||
@ -766,7 +766,7 @@ public:
|
||||
bool CanThisClassParry(void) const;
|
||||
bool CanThisClassBlock(void) const;
|
||||
|
||||
int GetMonkHandToHandDelay(void);
|
||||
int GetHandToHandDelay(void);
|
||||
uint32 GetClassLevelFactor();
|
||||
void Mesmerize();
|
||||
inline bool IsMezzed() const { return mezzed; }
|
||||
|
||||
48
zone/npc.cpp
48
zone/npc.cpp
@ -843,6 +843,54 @@ bool NPC::DatabaseCastAccepted(int spell_id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NPC::SpawnZoneController(){
|
||||
|
||||
if (!RuleB(Zone, UseZoneController))
|
||||
return false;
|
||||
|
||||
NPCType* npc_type = new NPCType;
|
||||
memset(npc_type, 0, sizeof(NPCType));
|
||||
|
||||
strncpy(npc_type->name, "zone_controller", 60);
|
||||
npc_type->cur_hp = 2000000000;
|
||||
npc_type->max_hp = 2000000000;
|
||||
npc_type->hp_regen = 100000000;
|
||||
npc_type->race = 240;
|
||||
npc_type->size = .1;
|
||||
npc_type->gender = 2;
|
||||
npc_type->class_ = 1;
|
||||
npc_type->deity = 1;
|
||||
npc_type->level = 200;
|
||||
npc_type->npc_id = ZONE_CONTROLLER_NPC_ID;
|
||||
npc_type->loottable_id = 0;
|
||||
npc_type->texture = 3;
|
||||
npc_type->runspeed = 0;
|
||||
npc_type->d_melee_texture1 = 0;
|
||||
npc_type->d_melee_texture2 = 0;
|
||||
npc_type->merchanttype = 0;
|
||||
npc_type->bodytype = 11;
|
||||
|
||||
npc_type->prim_melee_type = 28;
|
||||
npc_type->sec_melee_type = 28;
|
||||
|
||||
npc_type->findable = 0;
|
||||
npc_type->trackable = 0;
|
||||
|
||||
strcpy(npc_type->special_abilities, "12,1^13,1^14,1^15,1^16,1^17,1^19,1^22,1^24,1^25,1^28,1^31,1^35,1^39,1^42,1");
|
||||
|
||||
glm::vec4 point;
|
||||
point.x = 3000;
|
||||
point.y = 1000;
|
||||
point.z = 500;
|
||||
|
||||
NPC* npc = new NPC(npc_type, nullptr, point, FlyMode3);
|
||||
npc->GiveNPCTypeData(npc_type);
|
||||
|
||||
entity_list.AddNPC(npc);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
NPC* NPC::SpawnNPC(const char* spawncommand, const glm::vec4& position, Client* client) {
|
||||
if(spawncommand == 0 || spawncommand[0] == 0) {
|
||||
return 0;
|
||||
|
||||
@ -96,6 +96,7 @@ class NPC : public Mob
|
||||
{
|
||||
public:
|
||||
static NPC* SpawnNPC(const char* spawncommand, const glm::vec4& position, Client* client = nullptr);
|
||||
static bool SpawnZoneController();
|
||||
static int8 GetAILevel(bool iForceReRead = false);
|
||||
|
||||
NPC(const NPCType* data, Spawn2* respawn, const glm::vec4& position, int iflymode, bool IsCorpse = false);
|
||||
|
||||
@ -4721,12 +4721,12 @@ XS(XS_Mob_GetHaste)
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
XS(XS_Mob_GetMonkHandToHandDamage); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_Mob_GetMonkHandToHandDamage)
|
||||
XS(XS_Mob_GetHandToHandDamage); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_Mob_GetHandToHandDamage)
|
||||
{
|
||||
dXSARGS;
|
||||
if (items != 1)
|
||||
Perl_croak(aTHX_ "Usage: Mob::GetMonkHandToHandDamage(THIS)");
|
||||
Perl_croak(aTHX_ "Usage: Mob::GetHandToHandDamage(THIS)");
|
||||
{
|
||||
Mob * THIS;
|
||||
int RETVAL;
|
||||
@ -4741,7 +4741,7 @@ XS(XS_Mob_GetMonkHandToHandDamage)
|
||||
if(THIS == nullptr)
|
||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||
|
||||
RETVAL = THIS->GetMonkHandToHandDamage();
|
||||
RETVAL = THIS->GetHandToHandDamage();
|
||||
XSprePUSH; PUSHi((IV)RETVAL);
|
||||
}
|
||||
XSRETURN(1);
|
||||
@ -4877,12 +4877,12 @@ XS(XS_Mob_CanThisClassParry)
|
||||
XSRETURN(1);
|
||||
}
|
||||
|
||||
XS(XS_Mob_GetMonkHandToHandDelay); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_Mob_GetMonkHandToHandDelay)
|
||||
XS(XS_Mob_GetHandToHandDelay); /* prototype to pass -Wmissing-prototypes */
|
||||
XS(XS_Mob_GetHandToHandDelay)
|
||||
{
|
||||
dXSARGS;
|
||||
if (items != 1)
|
||||
Perl_croak(aTHX_ "Usage: Mob::GetMonkHandToHandDelay(THIS)");
|
||||
Perl_croak(aTHX_ "Usage: Mob::GetHandToHandDelay(THIS)");
|
||||
{
|
||||
Mob * THIS;
|
||||
int RETVAL;
|
||||
@ -4897,7 +4897,7 @@ XS(XS_Mob_GetMonkHandToHandDelay)
|
||||
if(THIS == nullptr)
|
||||
Perl_croak(aTHX_ "THIS is nullptr, avoiding crash.");
|
||||
|
||||
RETVAL = THIS->GetMonkHandToHandDelay();
|
||||
RETVAL = THIS->GetHandToHandDelay();
|
||||
XSprePUSH; PUSHi((IV)RETVAL);
|
||||
}
|
||||
XSRETURN(1);
|
||||
@ -9192,13 +9192,13 @@ XS(boot_Mob)
|
||||
newXSproto(strcpy(buf, "GetInvul"), XS_Mob_GetInvul, file, "$");
|
||||
newXSproto(strcpy(buf, "SetExtraHaste"), XS_Mob_SetExtraHaste, file, "$$");
|
||||
newXSproto(strcpy(buf, "GetHaste"), XS_Mob_GetHaste, file, "$");
|
||||
newXSproto(strcpy(buf, "GetMonkHandToHandDamage"), XS_Mob_GetMonkHandToHandDamage, file, "$");
|
||||
newXSproto(strcpy(buf, "GetHandToHandDamage"), XS_Mob_GetHandToHandDamage, file, "$");
|
||||
newXSproto(strcpy(buf, "CanThisClassDoubleAttack"), XS_Mob_CanThisClassDoubleAttack, file, "$");
|
||||
newXSproto(strcpy(buf, "CanThisClassDualWield"), XS_Mob_CanThisClassDualWield, file, "$");
|
||||
newXSproto(strcpy(buf, "CanThisClassRiposte"), XS_Mob_CanThisClassRiposte, file, "$");
|
||||
newXSproto(strcpy(buf, "CanThisClassDodge"), XS_Mob_CanThisClassDodge, file, "$");
|
||||
newXSproto(strcpy(buf, "CanThisClassParry"), XS_Mob_CanThisClassParry, file, "$");
|
||||
newXSproto(strcpy(buf, "GetMonkHandToHandDelay"), XS_Mob_GetMonkHandToHandDelay, file, "$");
|
||||
newXSproto(strcpy(buf, "GetHandToHandDelay"), XS_Mob_GetHandToHandDelay, file, "$");
|
||||
newXSproto(strcpy(buf, "GetClassLevelFactor"), XS_Mob_GetClassLevelFactor, file, "$");
|
||||
newXSproto(strcpy(buf, "Mesmerize"), XS_Mob_Mesmerize, file, "$");
|
||||
newXSproto(strcpy(buf, "IsMezzed"), XS_Mob_IsMezzed, file, "$");
|
||||
|
||||
@ -484,10 +484,17 @@ QuestInterface *QuestParserCollection::GetQIByNPCQuest(uint32 npcid, std::string
|
||||
|
||||
//second look for /quests/zone/npcname.ext (precedence)
|
||||
const NPCType *npc_type = database.LoadNPCTypesData(npcid);
|
||||
if(!npc_type) {
|
||||
if (!npc_type && npcid != ZONE_CONTROLLER_NPC_ID) {
|
||||
return nullptr;
|
||||
}
|
||||
std::string npc_name = npc_type->name;
|
||||
|
||||
std::string npc_name;
|
||||
if (npcid == ZONE_CONTROLLER_NPC_ID){
|
||||
npc_name = "zone_controller";
|
||||
}
|
||||
else{
|
||||
npc_name = npc_type->name;
|
||||
}
|
||||
int sz = static_cast<int>(npc_name.length());
|
||||
for(int i = 0; i < sz; ++i) {
|
||||
if(npc_name[i] == '`') {
|
||||
|
||||
@ -2598,6 +2598,29 @@ void QuestManager::UpdateInstanceTimer(uint16 instance_id, uint32 new_duration)
|
||||
}
|
||||
}
|
||||
|
||||
uint32 QuestManager::GetInstanceTimer() {
|
||||
if (zone && zone->GetInstanceID() > 0 && zone->GetInstanceTimer()) {
|
||||
uint32 ttime = zone->GetInstanceTimer()->GetRemainingTime();
|
||||
return ttime;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32 QuestManager::GetInstanceTimerByID(uint16 instance_id) {
|
||||
if (instance_id == 0)
|
||||
return 0;
|
||||
|
||||
std::string query = StringFormat("SELECT ((start_time + duration) - UNIX_TIMESTAMP()) AS `remaining` FROM `instance_list` WHERE `id` = %lu", (unsigned long)instance_id);
|
||||
auto results = database.QueryDatabase(query);
|
||||
|
||||
if (results.Success()) {
|
||||
auto row = results.begin();
|
||||
uint32 timer = atoi(row[0]);
|
||||
return timer;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16 QuestManager::GetInstanceID(const char *zone, int16 version)
|
||||
{
|
||||
QuestManagerCurrentQuestVars();
|
||||
@ -3070,3 +3093,75 @@ std::string QuestManager::GetEncounter() const {
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
void QuestManager::UpdateZoneHeader(std::string type, std::string value) {
|
||||
if (strcasecmp(type.c_str(), "ztype") == 0)
|
||||
zone->newzone_data.ztype = atoi(value.c_str());
|
||||
else if (strcasecmp(type.c_str(), "fog_red") == 0) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
zone->newzone_data.fog_red[i] = atoi(value.c_str());
|
||||
}
|
||||
} else if (strcasecmp(type.c_str(), "fog_green") == 0) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
zone->newzone_data.fog_green[i] = atoi(value.c_str());
|
||||
}
|
||||
} else if (strcasecmp(type.c_str(), "fog_blue") == 0) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
zone->newzone_data.fog_blue[i] = atoi(value.c_str());
|
||||
}
|
||||
} else if (strcasecmp(type.c_str(), "fog_minclip") == 0) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
zone->newzone_data.fog_minclip[i] = atof(value.c_str());
|
||||
}
|
||||
} else if (strcasecmp(type.c_str(), "fog_maxclip") == 0) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
zone->newzone_data.fog_maxclip[i] = atof(value.c_str());
|
||||
}
|
||||
}
|
||||
else if (strcasecmp(type.c_str(), "gravity") == 0)
|
||||
zone->newzone_data.gravity = atof(value.c_str());
|
||||
else if (strcasecmp(type.c_str(), "time_type") == 0)
|
||||
zone->newzone_data.time_type = atoi(value.c_str());
|
||||
else if (strcasecmp(type.c_str(), "rain_chance") == 0) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
zone->newzone_data.rain_chance[i] = atoi(value.c_str());
|
||||
}
|
||||
} else if (strcasecmp(type.c_str(), "rain_duration") == 0) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
zone->newzone_data.rain_duration[i] = atoi(value.c_str());
|
||||
}
|
||||
} else if (strcasecmp(type.c_str(), "snow_chance") == 0) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
zone->newzone_data.snow_chance[i] = atoi(value.c_str());
|
||||
}
|
||||
} else if (strcasecmp(type.c_str(), "snow_duration") == 0) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
zone->newzone_data.snow_duration[i] = atoi(value.c_str());
|
||||
}
|
||||
}
|
||||
else if (strcasecmp(type.c_str(), "sky") == 0)
|
||||
zone->newzone_data.sky = atoi(value.c_str());
|
||||
else if (strcasecmp(type.c_str(), "safe_x") == 0)
|
||||
zone->newzone_data.safe_x = atof(value.c_str());
|
||||
else if (strcasecmp(type.c_str(), "safe_y") == 0)
|
||||
zone->newzone_data.safe_y = atof(value.c_str());
|
||||
else if (strcasecmp(type.c_str(), "safe_z") == 0)
|
||||
zone->newzone_data.safe_z = atof(value.c_str());
|
||||
else if (strcasecmp(type.c_str(), "max_z") == 0)
|
||||
zone->newzone_data.max_z = atof(value.c_str());
|
||||
else if (strcasecmp(type.c_str(), "underworld") == 0)
|
||||
zone->newzone_data.underworld = atof(value.c_str());
|
||||
else if (strcasecmp(type.c_str(), "minclip") == 0)
|
||||
zone->newzone_data.minclip = atof(value.c_str());
|
||||
else if (strcasecmp(type.c_str(), "maxclip") == 0)
|
||||
zone->newzone_data.maxclip = atof(value.c_str());
|
||||
else if (strcasecmp(type.c_str(), "fog_density") == 0)
|
||||
zone->newzone_data.fog_density = atof(value.c_str());
|
||||
else if (strcasecmp(type.c_str(), "suspendbuffs") == 0)
|
||||
zone->newzone_data.SuspendBuffs = atoi(value.c_str());
|
||||
|
||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_NewZone, sizeof(NewZone_Struct));
|
||||
memcpy(outapp->pBuffer, &zone->newzone_data, outapp->size);
|
||||
entity_list.QueueClients(0, outapp);
|
||||
safe_delete(outapp);
|
||||
}
|
||||
@ -218,6 +218,9 @@ public:
|
||||
uint32 MerchantCountItem(uint32 NPCid, uint32 itemid);
|
||||
uint16 CreateInstance(const char *zone, int16 version, uint32 duration);
|
||||
void UpdateInstanceTimer(uint16 instance_id, uint32 new_duration);
|
||||
void UpdateZoneHeader(std::string type, std::string value);
|
||||
uint32 GetInstanceTimer();
|
||||
uint32 GetInstanceTimerByID(uint16 instance_id = 0);
|
||||
void DestroyInstance(uint16 instance_id);
|
||||
uint16 GetInstanceID(const char *zone, int16 version);
|
||||
void AssignToInstance(uint16 instance_id);
|
||||
|
||||
@ -549,6 +549,8 @@ bool ZoneDatabase::PopulateZoneSpawnList(uint32 zoneid, LinkedList<Spawn2*> &spa
|
||||
spawn2_list.Insert(new_spawn);
|
||||
}
|
||||
|
||||
NPC::SpawnZoneController();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -1268,6 +1268,14 @@ void Mob::CastedSpellFinished(uint16 spell_id, uint32 target_id, uint16 slot,
|
||||
}
|
||||
}
|
||||
|
||||
// we're done casting, now try to apply the spell
|
||||
if( !SpellFinished(spell_id, spell_target, slot, mana_used, inventory_slot, resist_adjust) )
|
||||
{
|
||||
Log.Out(Logs::Detail, Logs::Spells, "Casting of %d canceled: SpellFinished returned false.", spell_id);
|
||||
InterruptSpell();
|
||||
return;
|
||||
}
|
||||
|
||||
if(IsClient()) {
|
||||
CheckNumHitsRemaining(NumHit::MatchingSpells);
|
||||
TrySympatheticProc(target, spell_id);
|
||||
@ -1277,14 +1285,6 @@ void Mob::CastedSpellFinished(uint16 spell_id, uint32 target_id, uint16 slot,
|
||||
|
||||
TryTriggerOnCast(spell_id, 0);
|
||||
|
||||
// we're done casting, now try to apply the spell
|
||||
if( !SpellFinished(spell_id, spell_target, slot, mana_used, inventory_slot, resist_adjust) )
|
||||
{
|
||||
Log.Out(Logs::Detail, Logs::Spells, "Casting of %d canceled: SpellFinished returned false.", spell_id);
|
||||
InterruptSpell();
|
||||
return;
|
||||
}
|
||||
|
||||
if(DeleteChargeFromSlot >= 0)
|
||||
CastToClient()->DeleteItemInInventory(DeleteChargeFromSlot, 1, true);
|
||||
|
||||
@ -5310,6 +5310,7 @@ void Client::SendBuffDurationPacket(Buffs_Struct &buff)
|
||||
EQApplicationPacket* outapp;
|
||||
outapp = new EQApplicationPacket(OP_Buff, sizeof(SpellBuffFade_Struct));
|
||||
SpellBuffFade_Struct* sbf = (SpellBuffFade_Struct*) outapp->pBuffer;
|
||||
int index;
|
||||
|
||||
sbf->entityid = GetID();
|
||||
sbf->slot = 2;
|
||||
@ -5317,6 +5318,19 @@ void Client::SendBuffDurationPacket(Buffs_Struct &buff)
|
||||
sbf->slotid = 0;
|
||||
sbf->level = buff.casterlevel > 0 ? buff.casterlevel : GetLevel();
|
||||
|
||||
// We really don't know what to send as sbf->effect.
|
||||
// The code used to send level (and still does for cases we don't know)
|
||||
//
|
||||
// The fixes below address known issues with sending level in this field.
|
||||
// Typically, when the packet is sent, or when the user
|
||||
// next does something on the UI that causes an update (like opening a
|
||||
// pack), the stats updated by the spell in question get corrupted.
|
||||
//
|
||||
// The values were determined by trial and error. I could not find a
|
||||
// pattern or find a field in spells_new that would work.
|
||||
|
||||
sbf->effect=sbf->level;
|
||||
|
||||
if (IsEffectInSpell(buff.spellid, SE_TotalHP))
|
||||
{
|
||||
// If any of the lower 6 bits are set, the GUI changes MAX_HP AGAIN.
|
||||
@ -5327,25 +5341,45 @@ void Client::SendBuffDurationPacket(Buffs_Struct &buff)
|
||||
else if (IsEffectInSpell(buff.spellid, SE_CurrentHP))
|
||||
{
|
||||
// This is mostly a problem when we try and update duration on a
|
||||
// dot or a hp->mana conversion. Zero cancels the effect, any
|
||||
// other value has the GUI doing that value at the same time server
|
||||
// is doing theirs. This makes the two match.
|
||||
int index = GetSpellEffectIndex(buff.spellid, SE_CurrentHP);
|
||||
// dot or a hp->mana conversion. Zero cancels the effect
|
||||
// Sending teh actual change again seems to work.
|
||||
index = GetSpellEffectIndex(buff.spellid, SE_CurrentHP);
|
||||
sbf->effect = abs(spells[buff.spellid].base[index]);
|
||||
}
|
||||
else if (IsEffectInSpell(buff.spellid, SE_SeeInvis))
|
||||
{
|
||||
// Wish I knew what this sbf->effect field was trying to tell
|
||||
// the client. 10 seems to not break SeeInvis spells. Level,
|
||||
// 10 seems to not break SeeInvis spells. Level,
|
||||
// which is what the old client sends breaks the client at at
|
||||
// least level 9, maybe more.
|
||||
sbf->effect = 10;
|
||||
}
|
||||
else
|
||||
else if (IsEffectInSpell(buff.spellid, SE_ArmorClass) ||
|
||||
IsEffectInSpell(buff.spellid, SE_ResistFire) ||
|
||||
IsEffectInSpell(buff.spellid, SE_ResistCold) ||
|
||||
IsEffectInSpell(buff.spellid, SE_ResistPoison) ||
|
||||
IsEffectInSpell(buff.spellid, SE_ResistDisease) ||
|
||||
IsEffectInSpell(buff.spellid, SE_ResistMagic) ||
|
||||
IsEffectInSpell(buff.spellid, SE_STR) ||
|
||||
IsEffectInSpell(buff.spellid, SE_STA) ||
|
||||
IsEffectInSpell(buff.spellid, SE_DEX) ||
|
||||
IsEffectInSpell(buff.spellid, SE_WIS) ||
|
||||
IsEffectInSpell(buff.spellid, SE_INT) ||
|
||||
IsEffectInSpell(buff.spellid, SE_AGI))
|
||||
{
|
||||
// Default to what old code did until we find a better fix for
|
||||
// other spell lines.
|
||||
sbf->effect=sbf->level;
|
||||
// This seems to work. Previosly stats got corrupted when sending
|
||||
// level.
|
||||
sbf->effect = 46;
|
||||
}
|
||||
else if (IsEffectInSpell(buff.spellid, SE_CHA))
|
||||
{
|
||||
index = GetSpellEffectIndex(buff.spellid, SE_CHA);
|
||||
sbf->effect = abs(spells[buff.spellid].base[index]);
|
||||
// Only use this valie if its not a spacer.
|
||||
if (sbf->effect != 0)
|
||||
{
|
||||
// Same as other stats, need this to prevent a double update.
|
||||
sbf->effect = 46;
|
||||
}
|
||||
}
|
||||
|
||||
sbf->bufffade = 0;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user