Compare commits

...

17 Commits

Author SHA1 Message Date
Akkadius 7e94f0ac72 [Release] 22.47.0 2024-03-05 22:18:16 -06:00
Chris Miles 2aa19f4cae [Release] 22.47.0 (#4164) 2024-03-05 22:04:35 -06:00
Mitch Freeman 805829f15d [Crash Fix] Added a guild_mgr check (#4163)
* CrashFix and Cleanup

* Formatting, add safe_delete

---------

Co-authored-by: Akkadius <akkadius1@gmail.com>
2024-03-05 22:00:08 -06:00
Alex King 2c2a8cdb63 [Bug Fix] Fix Character EXP Modifiers default (#4161)
# Notes
- The `-1.0f` was causing these modifiers to be set to `0.0` and when people would enable them they would get no experience.
- We now use the zone based grabbed methods when setting which will default to a value of `1.0f` if there is not a value found.
2024-03-05 21:54:07 -06:00
Chris Miles ee3d02bac6 [Zoning] Zone routing adjustment (#4162) 2024-03-05 21:53:07 -06:00
Alex King b90139bd9a [Feature] Adjust String-based Rules Length (#4138) 2024-03-05 21:52:34 -06:00
catapultam-habeo e6a3d5e1c5 [Bug Fix] Prevent NPE when creating DZ using ad-hoc version IDs (#4141)
* initial commit

* corrected based on hgtw feedback
2024-03-05 18:21:04 -05:00
Alex King 74f1eac401 [Bug Fix] Fix Spawns Not Parsing Quest on Zone Bootup (#4149)
* Update zone.cpp

* Fix

---------

Co-authored-by: Natedog2012 <jwalters_06@yahoo.com>
2024-03-05 18:20:42 -05:00
JJ 1be9b2cdfd [Bug Fix] Fix typo when updating spawn events in spawn condition manager (#4160) 2024-03-05 05:44:38 -05:00
Mitch Freeman add0a8dddf [Bug Fix] Add id to the guild_bank table (#4155)
* Add id to guild_bank table

Add id as a primary key to guild_bank

* Remove content schema update flag
2024-03-04 19:02:35 -05:00
catapultam-habeo 8c226054e7 [Feature] Adds rules to control level requirements for Double Backstab, Assassinate, and Double Bowshot (#29) (#4159)
Co-authored-by: mute <natanx@gmail.com>
2024-03-04 18:41:25 -05:00
Mitch Freeman b4605f77e3 [Crash Fix] Goto Command could crash using Developer Tools (#4158) 2024-03-03 22:33:12 -05:00
Mitch Freeman 74a63daf7e [Crash Fix] Groundspawn Memory Corruption (#4157) 2024-03-03 22:32:29 -05:00
Alex King 8ee7910569 [Quest API] Add IsAlwaysAggro() to Perl/Lua (#4152)
- Add `$mob->IsAlwaysAggro()`.

- Add `mob:IsAlwaysAggro()`.

- Allows operators to determine if a mob is set to always aggro.
2024-03-03 20:40:20 -05:00
Alex King b766a79c11 [Quest API] Add GetHeroicStrikethrough() to Perl/Lua (#4150)
- Add `$mob->GetHeroicStrikethrough()`.

- Add `mob:GetHeroicStrikethrough()`.

- Allows operators to get a mob's Heroic Strikethrough.
2024-03-03 13:05:01 -05:00
Alex King 5e3b6d363a [Quest API] Add IsBoat()/IsControllableBoat() to Perl/Lua (#4151)
- Add `$mob->IsBoat()`.
- Add `$mob->IsControllableBoat()`.

- Add `mob:IsBoat()`.
- Add `mob:IsControllableBoat()`.

- Allows operators to determine if a mob is a boat or a controllable boat.
2024-03-03 12:34:21 -05:00
Alex King b2fc59878a [Quest API] Add IsDestructibleObject() to Perl/Lua (#4153)
# Perl
- Add `$mob-.IsDestructibleObject()`.

# Lua
- Add `mob:IsDestructibleObject()`.

# Notes
- Allows operators to determine if a mob is a destructible object.
2024-03-03 11:43:54 -05:00
20 changed files with 264 additions and 44 deletions
+42
View File
@@ -1,3 +1,45 @@
## [22.47.0] 3/5/2024
### Crash Fix
* Added a guild_mgr check ([#4163](https://github.com/EQEmu/Server/pull/4163)) @neckkola 2024-03-06
* Goto Command could crash using Developer Tools ([#4158](https://github.com/EQEmu/Server/pull/4158)) @neckkola 2024-03-04
* Groundspawn Memory Corruption ([#4157](https://github.com/EQEmu/Server/pull/4157)) @neckkola 2024-03-04
* Update to location of qGlobals initialization ([#4144](https://github.com/EQEmu/Server/pull/4144)) @neckkola 2024-03-02
### Feature
* Adds rules to control level requirements for Double Backstab, Assassinate, and Double Bowshot (#4159) ([#29](https://github.com/EQEmu/Server/pull/29)) @catapultam-habeo 2024-03-04
* Adjust String-based Rules Length ([#4138](https://github.com/EQEmu/Server/pull/4138)) @Kinglykrab 2024-03-06
* Exempt a zone from IP-limit checks. ([#4137](https://github.com/EQEmu/Server/pull/4137)) @catapultam-habeo 2024-03-02
### Fixes
* Add id to the guild_bank table ([#4155](https://github.com/EQEmu/Server/pull/4155)) @neckkola 2024-03-05
* Fix Bots/Bot Pets ending up on XTargets ([#4132](https://github.com/EQEmu/Server/pull/4132)) @Kinglykrab 2024-03-02
* Fix Character EXP Modifiers default ([#4161](https://github.com/EQEmu/Server/pull/4161)) @Kinglykrab 2024-03-06
* Fix Spawns Not Parsing Quest on Zone Bootup ([#4149](https://github.com/EQEmu/Server/pull/4149)) @Kinglykrab 2024-03-05
* Fix typo when updating spawn events in spawn condition manager ([#4160](https://github.com/EQEmu/Server/pull/4160)) @joligario 2024-03-05
* GetBotNameByID Temporary Reference Warning ([#4145](https://github.com/EQEmu/Server/pull/4145)) @Kinglykrab 2024-03-02
* Prevent NPE when creating DZ using ad-hoc version IDs ([#4141](https://github.com/EQEmu/Server/pull/4141)) @catapultam-habeo 2024-03-05
* Update FreeGuildID Routine ([#4143](https://github.com/EQEmu/Server/pull/4143)) @neckkola 2024-03-02
### Quest API
* Add Bot Special Attacks for Immune Aggro/Damage ([#4108](https://github.com/EQEmu/Server/pull/4108)) @Kinglykrab 2024-03-02
* Add GetHeroicStrikethrough() to Perl/Lua ([#4150](https://github.com/EQEmu/Server/pull/4150)) @Kinglykrab 2024-03-03
* Add IsAlwaysAggro() to Perl/Lua ([#4152](https://github.com/EQEmu/Server/pull/4152)) @Kinglykrab 2024-03-04
* Add IsBoat()/IsControllableBoat() to Perl/Lua ([#4151](https://github.com/EQEmu/Server/pull/4151)) @Kinglykrab 2024-03-03
* Add IsDestructibleObject() to Perl/Lua ([#4153](https://github.com/EQEmu/Server/pull/4153)) @Kinglykrab 2024-03-03
### Zone
* Zone Routing Improvements ([#4142](https://github.com/EQEmu/Server/pull/4142)) @Akkadius 2024-03-02
### Zoning
* Zone routing adjustment ([#4162](https://github.com/EQEmu/Server/pull/4162)) @Akkadius 2024-03-06
## [22.46.1] 3/2/2024 ## [22.46.1] 3/2/2024
### Fixes ### Fixes
+9 -4
View File
@@ -287,9 +287,14 @@ WorldContentService * WorldContentService::LoadZones()
// era contextual routing, multiple version of zones, etc // era contextual routing, multiple version of zones, etc
WorldContentService::FindZoneResult WorldContentService::FindZone(uint32 zone_id, uint32 instance_id) WorldContentService::FindZoneResult WorldContentService::FindZone(uint32 zone_id, uint32 instance_id)
{ {
// if we're already in a regular instance, we don't want to route the player to another instance // if there's an active dynamic instance, we don't need to route
if (instance_id > RuleI(Instances, ReservedInstances)) { if (instance_id > 0) {
return WorldContentService::FindZoneResult{}; auto inst = InstanceListRepository::FindOne(*GetDatabase(), instance_id);
if (inst.id != 0 && !inst.is_global && !inst.never_expires) {
return WorldContentService::FindZoneResult{
.zone_id = 0,
};
}
} }
for (auto &z: m_zones) { for (auto &z: m_zones) {
@@ -349,6 +354,6 @@ WorldContentService::FindZoneResult WorldContentService::FindZone(uint32 zone_id
} }
} }
return WorldContentService::FindZoneResult{}; return WorldContentService::FindZoneResult{.zone_id = 0};
} }
@@ -5410,6 +5410,29 @@ ADD COLUMN `augment_five` int(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `augment_fou
ADD COLUMN `augment_six` int(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `augment_five`; ADD COLUMN `augment_six` int(11) UNSIGNED NOT NULL DEFAULT 0 AFTER `augment_five`;
)", )",
.content_schema_update = true .content_schema_update = true
},
ManifestEntry{
.version = 9265,
.description = "2024_03_03_add_id_to_guild_bank.sql",
.check = "SHOW COLUMNS FROM `guild_bank` LIKE 'id'",
.condition = "empty",
.match = "",
.sql = R"(
ALTER TABLE `guild_bank`
ADD COLUMN `id` INT UNSIGNED NOT NULL AUTO_INCREMENT FIRST,
ADD PRIMARY KEY (`id`);
)",
},
ManifestEntry{
.version = 9266,
.description = "2024_03_02_rule_values_rule_value_length.sql",
.check = "SHOW COLUMNS FROM `rule_values` LIKE 'rule_value'",
.condition = "contains",
.match = "varchar(30)",
.sql = R"(
ALTER TABLE `rule_values`
MODIFY COLUMN `rule_value` text CHARACTER SET latin1 COLLATE latin1_swedish_ci NOT NULL DEFAULT '' AFTER `rule_name`;
)"
} }
// -- template; copy/paste this when you need to create a new entry // -- template; copy/paste this when you need to create a new entry
// ManifestEntry{ // ManifestEntry{
@@ -74,9 +74,11 @@ public:
}; };
} }
const auto& m = l.front();
return EXPModifier{ return EXPModifier{
.aa_modifier = l[0].aa_modifier, .aa_modifier = m.aa_modifier,
.exp_modifier = l[0].exp_modifier .exp_modifier = m.exp_modifier
}; };
} }
+3
View File
@@ -527,6 +527,7 @@ RULE_REAL(Combat, BaseProcChance, 0.035, "Base chance for procs")
RULE_REAL(Combat, ProcDexDivideBy, 11000, "Divisor for the probability of a proc increased by dexterity") RULE_REAL(Combat, ProcDexDivideBy, 11000, "Divisor for the probability of a proc increased by dexterity")
RULE_INT(Combat, MinRangedAttackDist, 25, "Minimum Distance to use Ranged Attacks") RULE_INT(Combat, MinRangedAttackDist, 25, "Minimum Distance to use Ranged Attacks")
RULE_BOOL(Combat, ArcheryBonusRequiresStationary, true, "does the 2x archery bonus chance require a stationary npc") RULE_BOOL(Combat, ArcheryBonusRequiresStationary, true, "does the 2x archery bonus chance require a stationary npc")
RULE_INT(Combat, ArcheryBonusLevelRequirement, 51, "Level requirement when the 2x archery bonus will be enabled. The default is 51.")
RULE_REAL(Combat, ArcheryNPCMultiplier, 1.0, "Value is multiplied by the regular dmg to get the archery dmg") RULE_REAL(Combat, ArcheryNPCMultiplier, 1.0, "Value is multiplied by the regular dmg to get the archery dmg")
RULE_BOOL(Combat, AssistNoTargetSelf, true, "When assisting a target that does not have a target: true = target self, false = leave target as was before assist (false = live like)") RULE_BOOL(Combat, AssistNoTargetSelf, true, "When assisting a target that does not have a target: true = target self, false = leave target as was before assist (false = live like)")
RULE_INT(Combat, MaxRampageTargets, 3, "Maximum number of people hit with rampage") RULE_INT(Combat, MaxRampageTargets, 3, "Maximum number of people hit with rampage")
@@ -575,10 +576,12 @@ RULE_BOOL(Combat, NPCsUseFrontalStunImmunityClasses, false, "Enable or disable N
RULE_INT(Combat, FrontalStunImmunityRaces, 512, "Bitmask for Races than have frontal stun immunity, Ogre (512) only by default.") RULE_INT(Combat, FrontalStunImmunityRaces, 512, "Bitmask for Races than have frontal stun immunity, Ogre (512) only by default.")
RULE_BOOL(Combat, NPCsUseFrontalStunImmunityRaces, true, "Enable or disable NPCs using frontal stun immunity Races from Combat:FrontalStunImmunityRaces, true by default.") RULE_BOOL(Combat, NPCsUseFrontalStunImmunityRaces, true, "Enable or disable NPCs using frontal stun immunity Races from Combat:FrontalStunImmunityRaces, true by default.")
RULE_BOOL(Combat, AssassinateOnlyHumanoids, true, "Enable or disable Assassinate only being allowed on Humanoids, true by default.") RULE_BOOL(Combat, AssassinateOnlyHumanoids, true, "Enable or disable Assassinate only being allowed on Humanoids, true by default.")
RULE_INT(Combat, AssassinateLevelRequirement, 60, "Level requirement to enable assassinate attempts on backstabs. The default is 60.")
RULE_BOOL(Combat, HeadshotOnlyHumanoids, true, "Enable or disable Headshot only being allowed on Humanoids, true by default.") RULE_BOOL(Combat, HeadshotOnlyHumanoids, true, "Enable or disable Headshot only being allowed on Humanoids, true by default.")
RULE_BOOL(Combat, EnableWarriorShielding, true, "Enable or disable Warrior Shielding Ability (/shield), true by default.") RULE_BOOL(Combat, EnableWarriorShielding, true, "Enable or disable Warrior Shielding Ability (/shield), true by default.")
RULE_BOOL(Combat, BackstabIgnoresElemental, false, "Enable or disable Elemental weapon damage affecting backstab damage, false by default.") RULE_BOOL(Combat, BackstabIgnoresElemental, false, "Enable or disable Elemental weapon damage affecting backstab damage, false by default.")
RULE_BOOL(Combat, BackstabIgnoresBane, false, "Enable or disable Bane weapon damage affecting backstab damage, false by default.") RULE_BOOL(Combat, BackstabIgnoresBane, false, "Enable or disable Bane weapon damage affecting backstab damage, false by default.")
RULE_INT(Combat, DoubleBackstabLevelRequirement, 55, "Level requirement to enable double backstab attempts. The default is 55.")
RULE_BOOL(Combat, SummonMeleeRange, true, "Enable or disable summoning of a player when already in melee range of the summoner.") RULE_BOOL(Combat, SummonMeleeRange, true, "Enable or disable summoning of a player when already in melee range of the summoner.")
RULE_BOOL(Combat, WaterMatchRequiredForAutoFireLoS, true, "Enable/Disable the requirement of both the attacker/victim being both in or out of water for AutoFire LoS to pass.") RULE_BOOL(Combat, WaterMatchRequiredForAutoFireLoS, true, "Enable/Disable the requirement of both the attacker/victim being both in or out of water for AutoFire LoS to pass.")
RULE_INT(Combat, ExtraAllowedKickClassesBitmask, 0, "Bitmask for allowing extra classes beyond Warrior, Ranger, Beastlord, and Berserker to kick, No Extra Classes (0) by default") RULE_INT(Combat, ExtraAllowedKickClassesBitmask, 0, "Bitmask for allowing extra classes beyond Warrior, Ranger, Beastlord, and Berserker to kick, No Extra Classes (0) by default")
+2 -2
View File
@@ -25,7 +25,7 @@
// Build variables // Build variables
// these get injected during the build pipeline // these get injected during the build pipeline
#define CURRENT_VERSION "22.46.1-dev" // always append -dev to the current version for custom-builds #define CURRENT_VERSION "22.47.0-dev" // always append -dev to the current version for custom-builds
#define LOGIN_VERSION "0.8.0" #define LOGIN_VERSION "0.8.0"
#define COMPILE_DATE __DATE__ #define COMPILE_DATE __DATE__
#define COMPILE_TIME __TIME__ #define COMPILE_TIME __TIME__
@@ -42,7 +42,7 @@
* Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt * Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
*/ */
#define CURRENT_BINARY_DATABASE_VERSION 9264 #define CURRENT_BINARY_DATABASE_VERSION 9266
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9043 #define CURRENT_BINARY_BOTS_DATABASE_VERSION 9043
#endif #endif
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "eqemu-server", "name": "eqemu-server",
"version": "22.46.1", "version": "22.47.0",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/EQEmu/Server.git" "url": "https://github.com/EQEmu/Server.git"
+1 -1
View File
@@ -6209,7 +6209,7 @@ void Mob::CommonOutgoingHitSuccess(Mob* defender, DamageHitInfo &hit, ExtraAttac
if (headshot > 0) { if (headshot > 0) {
hit.damage_done = headshot; hit.damage_done = headshot;
} }
else if (GetClass() == Class::Ranger && GetLevel() > 50) { // no double dmg on headshot else if (GetClass() == Class::Ranger && GetLevel() >= RuleI(Combat, ArcheryBonusLevelRequirement)) { // no double dmg on headshot
if ((defender->IsNPC() && !defender->IsMoving() && !defender->IsRooted()) || !RuleB(Combat, ArcheryBonusRequiresStationary)) { if ((defender->IsNPC() && !defender->IsMoving() && !defender->IsRooted()) || !RuleB(Combat, ArcheryBonusRequiresStationary)) {
hit.damage_done *= 2; hit.damage_done *= 2;
MessageString(Chat::MeleeCrit, BOW_DOUBLE_DAMAGE); MessageString(Chat::MeleeCrit, BOW_DOUBLE_DAMAGE);
+2 -1
View File
@@ -3,6 +3,7 @@
void command_goto(Client *c, const Seperator *sep) void command_goto(Client *c, const Seperator *sep)
{ {
std::string arg1 = sep->arg[1]; std::string arg1 = sep->arg[1];
std::string arg4 = sep->arg[4];
bool goto_via_target_no_args = sep->arg[1][0] == '\0' && c->GetTarget(); bool goto_via_target_no_args = sep->arg[1][0] == '\0' && c->GetTarget();
bool goto_via_player_name = !sep->IsNumber(1) && !arg1.empty(); bool goto_via_player_name = !sep->IsNumber(1) && !arg1.empty();
@@ -52,7 +53,7 @@ void command_goto(Client *c, const Seperator *sep)
Strings::ToFloat(sep->arg[1]), Strings::ToFloat(sep->arg[1]),
Strings::ToFloat(sep->arg[2]), Strings::ToFloat(sep->arg[2]),
Strings::ToFloat(sep->arg[3]), Strings::ToFloat(sep->arg[3]),
(sep->arg[4] ? Strings::ToFloat(sep->arg[4]) : c->GetHeading()) (!arg4.empty() ? Strings::ToFloat(sep->arg[4]) : c->GetHeading())
); );
} }
else { else {
+35
View File
@@ -3267,6 +3267,36 @@ bool Lua_Mob::IsPetOwnerNPC()
return self->IsPetOwnerNPC(); return self->IsPetOwnerNPC();
} }
bool Lua_Mob::IsDestructibleObject()
{
Lua_Safe_Call_Bool();
return self->IsDestructibleObject();
}
bool Lua_Mob::IsBoat()
{
Lua_Safe_Call_Bool();
return self->IsBoat();
}
bool Lua_Mob::IsControllableBoat()
{
Lua_Safe_Call_Bool();
return self->IsControllableBoat();
}
int Lua_Mob::GetHeroicStrikethrough()
{
Lua_Safe_Call_Int();
return self->GetHeroicStrikethrough();
}
bool Lua_Mob::IsAlwaysAggro()
{
Lua_Safe_Call_Bool();
return self->AlwaysAggro();
}
luabind::scope lua_register_mob() { luabind::scope lua_register_mob() {
return luabind::class_<Lua_Mob, Lua_Entity>("Mob") return luabind::class_<Lua_Mob, Lua_Entity>("Mob")
.def(luabind::constructor<>()) .def(luabind::constructor<>())
@@ -3546,6 +3576,7 @@ luabind::scope lua_register_mob() {
.def("GetHateTopNPC", (Lua_NPC(Lua_Mob::*)(void))&Lua_Mob::GetHateTopNPC) .def("GetHateTopNPC", (Lua_NPC(Lua_Mob::*)(void))&Lua_Mob::GetHateTopNPC)
.def("GetHeading", &Lua_Mob::GetHeading) .def("GetHeading", &Lua_Mob::GetHeading)
.def("GetHelmTexture", &Lua_Mob::GetHelmTexture) .def("GetHelmTexture", &Lua_Mob::GetHelmTexture)
.def("GetHeroicStrikethrough", &Lua_Mob::GetHeroicStrikethrough)
.def("GetHerosForgeModel", (int32(Lua_Mob::*)(uint8))&Lua_Mob::GetHerosForgeModel) .def("GetHerosForgeModel", (int32(Lua_Mob::*)(uint8))&Lua_Mob::GetHerosForgeModel)
.def("GetINT", &Lua_Mob::GetINT) .def("GetINT", &Lua_Mob::GetINT)
.def("GetInvisibleLevel", (uint8(Lua_Mob::*)(void))&Lua_Mob::GetInvisibleLevel) .def("GetInvisibleLevel", (uint8(Lua_Mob::*)(void))&Lua_Mob::GetInvisibleLevel)
@@ -3642,6 +3673,7 @@ luabind::scope lua_register_mob() {
.def("InterruptSpell", (void(Lua_Mob::*)(int))&Lua_Mob::InterruptSpell) .def("InterruptSpell", (void(Lua_Mob::*)(int))&Lua_Mob::InterruptSpell)
.def("InterruptSpell", (void(Lua_Mob::*)(void))&Lua_Mob::InterruptSpell) .def("InterruptSpell", (void(Lua_Mob::*)(void))&Lua_Mob::InterruptSpell)
.def("IsAIControlled", (bool(Lua_Mob::*)(void))&Lua_Mob::IsAIControlled) .def("IsAIControlled", (bool(Lua_Mob::*)(void))&Lua_Mob::IsAIControlled)
.def("IsAlwaysAggro", &Lua_Mob::IsAlwaysAggro)
.def("IsAmnesiad", (bool(Lua_Mob::*)(void))&Lua_Mob::IsAmnesiad) .def("IsAmnesiad", (bool(Lua_Mob::*)(void))&Lua_Mob::IsAmnesiad)
.def("IsAnimation", &Lua_Mob::IsAnimation) .def("IsAnimation", &Lua_Mob::IsAnimation)
.def("IsAttackAllowed", (bool(Lua_Mob::*)(Lua_Mob))&Lua_Mob::IsAttackAllowed) .def("IsAttackAllowed", (bool(Lua_Mob::*)(Lua_Mob))&Lua_Mob::IsAttackAllowed)
@@ -3649,8 +3681,11 @@ luabind::scope lua_register_mob() {
.def("IsBeneficialAllowed", (bool(Lua_Mob::*)(Lua_Mob))&Lua_Mob::IsBeneficialAllowed) .def("IsBeneficialAllowed", (bool(Lua_Mob::*)(Lua_Mob))&Lua_Mob::IsBeneficialAllowed)
.def("IsBerserk", &Lua_Mob::IsBerserk) .def("IsBerserk", &Lua_Mob::IsBerserk)
.def("IsBlind", (bool(Lua_Mob::*)(void))&Lua_Mob::IsBlind) .def("IsBlind", (bool(Lua_Mob::*)(void))&Lua_Mob::IsBlind)
.def("IsBoat", &Lua_Mob::IsBoat)
.def("IsCasting", &Lua_Mob::IsCasting) .def("IsCasting", &Lua_Mob::IsCasting)
.def("IsCharmed", &Lua_Mob::IsCharmed) .def("IsCharmed", &Lua_Mob::IsCharmed)
.def("IsControllableBoat", &Lua_Mob::IsControllableBoat)
.def("IsDestructibleObject", &Lua_Mob::IsDestructibleObject)
.def("IsEliteMaterialItem", (uint32(Lua_Mob::*)(uint8))&Lua_Mob::IsEliteMaterialItem) .def("IsEliteMaterialItem", (uint32(Lua_Mob::*)(uint8))&Lua_Mob::IsEliteMaterialItem)
.def("IsEngaged", (bool(Lua_Mob::*)(void))&Lua_Mob::IsEngaged) .def("IsEngaged", (bool(Lua_Mob::*)(void))&Lua_Mob::IsEngaged)
.def("IsEnraged", (bool(Lua_Mob::*)(void))&Lua_Mob::IsEnraged) .def("IsEnraged", (bool(Lua_Mob::*)(void))&Lua_Mob::IsEnraged)
+5
View File
@@ -577,6 +577,11 @@ public:
bool IsPetOwnerBot(); bool IsPetOwnerBot();
bool IsPetOwnerClient(); bool IsPetOwnerClient();
bool IsPetOwnerNPC(); bool IsPetOwnerNPC();
bool IsDestructibleObject();
bool IsBoat();
bool IsControllableBoat();
int GetHeroicStrikethrough();
bool IsAlwaysAggro();
}; };
#endif #endif
+30
View File
@@ -3395,6 +3395,31 @@ bool Perl_Mob_IsPetOwnerNPC(Mob* self)
return self->IsPetOwnerNPC(); return self->IsPetOwnerNPC();
} }
bool Perl_Mob_IsDestructibleObject(Mob* self)
{
return self->IsDestructibleObject();
}
bool Perl_Mob_IsBoat(Mob* self)
{
return self->IsBoat();
}
bool Perl_Mob_IsControllableBoat(Mob* self)
{
return self->IsControllableBoat();
}
int Perl_Mob_GetHeroicStrikethrough(Mob* self)
{
return self->GetHeroicStrikethrough();
}
bool Perl_Mob_IsAlwaysAggro(Mob* self)
{
return self->AlwaysAggro();
}
void perl_register_mob() void perl_register_mob()
{ {
perl::interpreter perl(PERL_GET_THX); perl::interpreter perl(PERL_GET_THX);
@@ -3660,6 +3685,7 @@ void perl_register_mob()
package.add("GetHateTopNPC", &Perl_Mob_GetHateTopNPC); package.add("GetHateTopNPC", &Perl_Mob_GetHateTopNPC);
package.add("GetHeading", &Perl_Mob_GetHeading); package.add("GetHeading", &Perl_Mob_GetHeading);
package.add("GetHelmTexture", &Perl_Mob_GetHelmTexture); package.add("GetHelmTexture", &Perl_Mob_GetHelmTexture);
package.add("GetHeroicStrikethrough", &Perl_Mob_GetHeroicStrikethrough);
package.add("GetHerosForgeModel", &Perl_Mob_GetHerosForgeModel); package.add("GetHerosForgeModel", &Perl_Mob_GetHerosForgeModel);
package.add("GetID", &Perl_Mob_GetID); package.add("GetID", &Perl_Mob_GetID);
package.add("GetINT", &Perl_Mob_GetINT); package.add("GetINT", &Perl_Mob_GetINT);
@@ -3759,6 +3785,7 @@ void perl_register_mob()
package.add("InterruptSpell", (void(*)(Mob*))&Perl_Mob_InterruptSpell); package.add("InterruptSpell", (void(*)(Mob*))&Perl_Mob_InterruptSpell);
package.add("InterruptSpell", (void(*)(Mob*, uint16))&Perl_Mob_InterruptSpell); package.add("InterruptSpell", (void(*)(Mob*, uint16))&Perl_Mob_InterruptSpell);
package.add("IsAIControlled", &Perl_Mob_IsAIControlled); package.add("IsAIControlled", &Perl_Mob_IsAIControlled);
package.add("IsAlwaysAggro", &Perl_Mob_IsAlwaysAggro);
package.add("IsAmnesiad", &Perl_Mob_IsAmnesiad); package.add("IsAmnesiad", &Perl_Mob_IsAmnesiad);
package.add("IsAnimation", &Perl_Mob_IsAnimation); package.add("IsAnimation", &Perl_Mob_IsAnimation);
package.add("IsAttackAllowed", (bool(*)(Mob*, Mob*))&Perl_Mob_IsAttackAllowed); package.add("IsAttackAllowed", (bool(*)(Mob*, Mob*))&Perl_Mob_IsAttackAllowed);
@@ -3768,11 +3795,14 @@ void perl_register_mob()
package.add("IsBeneficialAllowed", &Perl_Mob_IsBeneficialAllowed); package.add("IsBeneficialAllowed", &Perl_Mob_IsBeneficialAllowed);
package.add("IsBerserk", &Perl_Mob_IsBerserk); package.add("IsBerserk", &Perl_Mob_IsBerserk);
package.add("IsBlind", &Perl_Mob_IsBlind); package.add("IsBlind", &Perl_Mob_IsBlind);
package.add("IsBoat", &Perl_Mob_IsBoat);
package.add("IsBot", &Perl_Mob_IsBot); package.add("IsBot", &Perl_Mob_IsBot);
package.add("IsCasting", &Perl_Mob_IsCasting); package.add("IsCasting", &Perl_Mob_IsCasting);
package.add("IsCharmed", &Perl_Mob_IsCharmed); package.add("IsCharmed", &Perl_Mob_IsCharmed);
package.add("IsClient", &Perl_Mob_IsClient); package.add("IsClient", &Perl_Mob_IsClient);
package.add("IsControllableBoat", &Perl_Mob_IsControllableBoat);
package.add("IsCorpse", &Perl_Mob_IsCorpse); package.add("IsCorpse", &Perl_Mob_IsCorpse);
package.add("IsDestructibleObject", &Perl_Mob_IsDestructibleObject);
package.add("IsDoor", &Perl_Mob_IsDoor); package.add("IsDoor", &Perl_Mob_IsDoor);
package.add("IsEliteMaterialItem", &Perl_Mob_IsEliteMaterialItem); package.add("IsEliteMaterialItem", &Perl_Mob_IsEliteMaterialItem);
package.add("IsEncounter", &Perl_Mob_IsEncounter); package.add("IsEncounter", &Perl_Mob_IsEncounter);
+9 -9
View File
@@ -805,7 +805,7 @@ int QuestParserCollection::EventBotGlobal(
QuestInterface* QuestParserCollection::GetQIByNPCQuest(uint32 npc_id, std::string& filename) QuestInterface* QuestParserCollection::GetQIByNPCQuest(uint32 npc_id, std::string& filename)
{ {
if (!zone || !zone->IsLoaded()) { if (!zone) {
return nullptr; return nullptr;
} }
@@ -871,7 +871,7 @@ QuestInterface* QuestParserCollection::GetQIByNPCQuest(uint32 npc_id, std::strin
QuestInterface* QuestParserCollection::GetQIByPlayerQuest(std::string& filename) QuestInterface* QuestParserCollection::GetQIByPlayerQuest(std::string& filename)
{ {
if (!zone || !zone->IsLoaded()) { if (!zone) {
return nullptr; return nullptr;
} }
@@ -922,7 +922,7 @@ QuestInterface* QuestParserCollection::GetQIByPlayerQuest(std::string& filename)
QuestInterface* QuestParserCollection::GetQIByGlobalNPCQuest(std::string& filename) QuestInterface* QuestParserCollection::GetQIByGlobalNPCQuest(std::string& filename)
{ {
if (!zone || !zone->IsLoaded()) { if (!zone) {
return nullptr; return nullptr;
} }
@@ -947,7 +947,7 @@ QuestInterface* QuestParserCollection::GetQIByGlobalNPCQuest(std::string& filena
QuestInterface* QuestParserCollection::GetQIByGlobalPlayerQuest(std::string& filename) QuestInterface* QuestParserCollection::GetQIByGlobalPlayerQuest(std::string& filename)
{ {
if (!zone || !zone->IsLoaded()) { if (!zone) {
return nullptr; return nullptr;
} }
@@ -971,7 +971,7 @@ QuestInterface* QuestParserCollection::GetQIByGlobalPlayerQuest(std::string& fil
QuestInterface* QuestParserCollection::GetQIBySpellQuest(uint32 spell_id, std::string& filename) QuestInterface* QuestParserCollection::GetQIBySpellQuest(uint32 spell_id, std::string& filename)
{ {
if (!zone || !zone->IsLoaded()) { if (!zone) {
return nullptr; return nullptr;
} }
@@ -1023,7 +1023,7 @@ QuestInterface* QuestParserCollection::GetQIBySpellQuest(uint32 spell_id, std::s
QuestInterface* QuestParserCollection::GetQIByItemQuest(std::string item_script, std::string& filename) QuestInterface* QuestParserCollection::GetQIByItemQuest(std::string item_script, std::string& filename)
{ {
if (!zone || !zone->IsLoaded()) { if (!zone) {
return nullptr; return nullptr;
} }
@@ -1075,7 +1075,7 @@ QuestInterface* QuestParserCollection::GetQIByItemQuest(std::string item_script,
QuestInterface* QuestParserCollection::GetQIByEncounterQuest(std::string encounter_name, std::string& filename) QuestInterface* QuestParserCollection::GetQIByEncounterQuest(std::string encounter_name, std::string& filename)
{ {
if (!zone || !zone->IsLoaded()) { if (!zone) {
return nullptr; return nullptr;
} }
@@ -1125,7 +1125,7 @@ QuestInterface* QuestParserCollection::GetQIByEncounterQuest(std::string encount
QuestInterface* QuestParserCollection::GetQIByBotQuest(std::string& filename) QuestInterface* QuestParserCollection::GetQIByBotQuest(std::string& filename)
{ {
if (!zone || !zone->IsLoaded()) { if (!zone) {
return nullptr; return nullptr;
} }
@@ -1176,7 +1176,7 @@ QuestInterface* QuestParserCollection::GetQIByBotQuest(std::string& filename)
QuestInterface* QuestParserCollection::GetQIByGlobalBotQuest(std::string& filename) QuestInterface* QuestParserCollection::GetQIByGlobalBotQuest(std::string& filename)
{ {
if (!zone || !zone->IsLoaded()) { if (!zone) {
return nullptr; return nullptr;
} }
+1 -1
View File
@@ -807,7 +807,7 @@ void SpawnConditionManager::UpdateSpawnEvent(SpawnEvent &event)
e.next_month = event.next.month; e.next_month = event.next.month;
e.next_year = event.next.year; e.next_year = event.next.year;
e.enabled = event.enabled ? 1 : 0; e.enabled = event.enabled ? 1 : 0;
e.next_minute = event.strict; e.strict = event.strict ? 1 : 0;
SpawnEventsRepository::UpdateOne(database, e); SpawnEventsRepository::UpdateOne(database, e);
} }
+2 -2
View File
@@ -707,7 +707,7 @@ void Mob::TryBackstab(Mob *other, int ReuseTime) {
CastToClient()->Message(Chat::White,"Your fierce attack is executed with such grace, your target did not see it coming!"); CastToClient()->Message(Chat::White,"Your fierce attack is executed with such grace, your target did not see it coming!");
RogueBackstab(other,false,ReuseTime); RogueBackstab(other,false,ReuseTime);
if (level > 54) { if (level >= RuleI(Combat, DoubleBackstabLevelRequirement)) {
// TODO: 55-59 doesn't appear to match just checking double attack, 60+ does though // TODO: 55-59 doesn't appear to match just checking double attack, 60+ does though
if(IsClient() && CastToClient()->CheckDoubleAttack()) if(IsClient() && CastToClient()->CheckDoubleAttack())
{ {
@@ -2402,7 +2402,7 @@ int Mob::TryAssassinate(Mob *defender, EQ::skills::SkillType skillInUse)
if ( if (
defender && defender &&
!defender->IsClient() && !defender->IsClient() &&
GetLevel() >= 60 && GetLevel() >= RuleI(Combat, AssassinateLevelRequirement) &&
(skillInUse == EQ::skills::SkillBackstab || skillInUse == EQ::skills::SkillThrowing) && (skillInUse == EQ::skills::SkillBackstab || skillInUse == EQ::skills::SkillThrowing) &&
(defender->GetBodyType() == BT_Humanoid || !RuleB(Combat, AssassinateOnlyHumanoids)) && (defender->GetBodyType() == BT_Humanoid || !RuleB(Combat, AssassinateOnlyHumanoids)) &&
!defender->GetSpecialAbility(IMMUNE_ASSASSINATE) !defender->GetSpecialAbility(IMMUNE_ASSASSINATE)
+2 -2
View File
@@ -2290,8 +2290,8 @@ void ClientTaskState::CreateTaskDynamicZone(Client* client, int task_id, Dynamic
} }
// dz should be named the version-based zone name (used in choose zone window and dz window on live) // dz should be named the version-based zone name (used in choose zone window and dz window on live)
auto zone_info = zone_store.GetZone(dz_request.GetZoneID(), dz_request.GetZoneVersion()); auto zone_info = zone_store.GetZoneWithFallback(dz_request.GetZoneID(), dz_request.GetZoneVersion());
dz_request.SetName(zone_info->long_name.empty() ? task->title : zone_info->long_name); dz_request.SetName(zone_info && !zone_info->long_name.empty() ? zone_info->long_name : task->title);
dz_request.SetMinPlayers(task->min_players); dz_request.SetMinPlayers(task->min_players);
dz_request.SetMaxPlayers(task->max_players); dz_request.SetMaxPlayers(task->max_players);
+11 -9
View File
@@ -3696,29 +3696,31 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p)
} }
break; break;
} }
case ServerOP_GuildTributeUpdateDonations: case ServerOP_GuildTributeUpdateDonations: {
{ auto in = (GuildTributeUpdate *) pack->pBuffer;
GuildTributeUpdate* in = (GuildTributeUpdate*)pack->pBuffer; auto outapp = new EQApplicationPacket(OP_GuildOptInOut, sizeof(GuildTributeOptInOutReply_Struct));
auto data = (GuildTributeOptInOutReply_Struct *) outapp->pBuffer;
EQApplicationPacket* outapp = new EQApplicationPacket(OP_GuildOptInOut, sizeof(GuildTributeOptInOutReply_Struct));
GuildTributeOptInOutReply_Struct* data = (GuildTributeOptInOutReply_Struct*)outapp->pBuffer;
data->guild_id = in->guild_id; data->guild_id = in->guild_id;
strn0cpy(data->player_name, in->player_name, sizeof(data->player_name));
data->no_donations = in->member_favor; data->no_donations = in->member_favor;
data->tribute_toggle = in->member_enabled ? true : false; data->tribute_toggle = in->member_enabled ? true : false;
data->tribute_trophy_toggle = 0; // not yet implemented data->tribute_trophy_toggle = 0; // not yet implemented
data->time = in->member_time; data->time = in->member_time;
data->command = 1; data->command = 1;
strn0cpy(data->player_name, in->player_name, sizeof(data->player_name));
entity_list.QueueClientsGuild(outapp, in->guild_id); entity_list.QueueClientsGuild(outapp, in->guild_id);
safe_delete(outapp); safe_delete(outapp);
//my new items
outapp = new EQApplicationPacket(OP_GuildTributeToggleReply, sizeof(GuildTributeSendActive_Struct)); outapp = new EQApplicationPacket(OP_GuildTributeToggleReply, sizeof(GuildTributeSendActive_Struct));
GuildTributeSendActive_Struct *out = (GuildTributeSendActive_Struct *) outapp->pBuffer; auto out = (GuildTributeSendActive_Struct *) outapp->pBuffer;
auto guild = guild_mgr.GetGuildByGuildID(in->guild_id); auto guild = guild_mgr.GetGuildByGuildID(in->guild_id);
if (!guild) {
safe_delete(outapp)
return;
}
out->not_used = in->guild_id; out->not_used = in->guild_id;
out->guild_favor = guild->tribute.favor; out->guild_favor = guild->tribute.favor;
out->tribute_enabled = guild->tribute.enabled; out->tribute_enabled = guild->tribute.enabled;
+70 -3
View File
@@ -355,9 +355,7 @@ bool Zone::IsSpecialBindLocation(const glm::vec4& location)
//this also just loads into entity_list, not really into zone //this also just loads into entity_list, not really into zone
bool Zone::LoadGroundSpawns() { bool Zone::LoadGroundSpawns() {
GroundSpawns g; GroundSpawns g{};
memset(&g, 0, sizeof(g));
content_db.LoadGroundSpawns(zoneid, GetInstanceVersion(), &g); content_db.LoadGroundSpawns(zoneid, GetInstanceVersion(), &g);
@@ -3167,6 +3165,11 @@ void Zone::ClearEXPModifier(Client* c)
exp_modifiers.erase(c->CharacterID()); exp_modifiers.erase(c->CharacterID());
} }
void Zone::ClearEXPModifierByCharacterID(const uint32 character_id)
{
exp_modifiers.erase(character_id);
}
float Zone::GetAAEXPModifier(Client* c) float Zone::GetAAEXPModifier(Client* c)
{ {
const auto& l = exp_modifiers.find(c->CharacterID()); const auto& l = exp_modifiers.find(c->CharacterID());
@@ -3179,6 +3182,18 @@ float Zone::GetAAEXPModifier(Client* c)
return v.aa_modifier; return v.aa_modifier;
} }
float Zone::GetAAEXPModifierByCharacterID(const uint32 character_id)
{
const auto& l = exp_modifiers.find(character_id);
if (l == exp_modifiers.end()) {
return 1.0f;
}
const auto& v = l->second;
return v.aa_modifier;
}
float Zone::GetEXPModifier(Client* c) float Zone::GetEXPModifier(Client* c)
{ {
const auto& l = exp_modifiers.find(c->CharacterID()); const auto& l = exp_modifiers.find(c->CharacterID());
@@ -3191,6 +3206,18 @@ float Zone::GetEXPModifier(Client* c)
return v.exp_modifier; return v.exp_modifier;
} }
float Zone::GetEXPModifierByCharacterID(const uint32 character_id)
{
const auto& l = exp_modifiers.find(character_id);
if (l == exp_modifiers.end()) {
return 1.0f;
}
const auto& v = l->second;
return v.exp_modifier;
}
void Zone::SetAAEXPModifier(Client* c, float aa_modifier) void Zone::SetAAEXPModifier(Client* c, float aa_modifier)
{ {
auto l = exp_modifiers.find(c->CharacterID()); auto l = exp_modifiers.find(c->CharacterID());
@@ -3211,6 +3238,26 @@ void Zone::SetAAEXPModifier(Client* c, float aa_modifier)
); );
} }
void Zone::SetAAEXPModifierByCharacterID(const uint32 character_id, float aa_modifier)
{
auto l = exp_modifiers.find(character_id);
if (l == exp_modifiers.end()) {
return;
}
auto& m = l->second;
m.aa_modifier = aa_modifier;
CharacterExpModifiersRepository::SetEXPModifier(
database,
character_id,
GetZoneID(),
GetInstanceVersion(),
m
);
}
void Zone::SetEXPModifier(Client* c, float exp_modifier) void Zone::SetEXPModifier(Client* c, float exp_modifier)
{ {
auto l = exp_modifiers.find(c->CharacterID()); auto l = exp_modifiers.find(c->CharacterID());
@@ -3231,6 +3278,26 @@ void Zone::SetEXPModifier(Client* c, float exp_modifier)
); );
} }
void Zone::SetEXPModifierByCharacterID(const uint32 character_id, float exp_modifier)
{
auto l = exp_modifiers.find(character_id);
if (l == exp_modifiers.end()) {
return;
}
auto& m = l->second;
m.exp_modifier = exp_modifier;
CharacterExpModifiersRepository::SetEXPModifier(
database,
character_id,
GetZoneID(),
GetInstanceVersion(),
m
);
}
bool Zone::IsIdleWhenEmpty() const bool Zone::IsIdleWhenEmpty() const
{ {
return m_idle_when_empty; return m_idle_when_empty;
+5
View File
@@ -269,10 +269,15 @@ public:
void SendReloadMessage(std::string reload_type); void SendReloadMessage(std::string reload_type);
void ClearEXPModifier(Client* c); void ClearEXPModifier(Client* c);
void ClearEXPModifierByCharacterID(const uint32 character_id);
float GetAAEXPModifier(Client* c); float GetAAEXPModifier(Client* c);
float GetAAEXPModifierByCharacterID(const uint32 character_id);
float GetEXPModifier(Client* c); float GetEXPModifier(Client* c);
float GetEXPModifierByCharacterID(const uint32 character_id);
void SetAAEXPModifier(Client* c, float aa_modifier); void SetAAEXPModifier(Client* c, float aa_modifier);
void SetAAEXPModifierByCharacterID(const uint32 character_id, float aa_modifier);
void SetEXPModifier(Client* c, float exp_modifier); void SetEXPModifier(Client* c, float exp_modifier);
void SetEXPModifierByCharacterID(const uint32 character_id, float exp_modifier);
void AddAggroMob() { aggroedmobs++; } void AddAggroMob() { aggroedmobs++; }
void AddAuth(ServerZoneIncomingClient_Struct *szic); void AddAuth(ServerZoneIncomingClient_Struct *szic);
+2 -2
View File
@@ -4270,7 +4270,7 @@ void ZoneDatabase::SetAAEXPModifierByCharID(
instance_version, instance_version,
EXPModifier{ EXPModifier{
.aa_modifier = aa_modifier, .aa_modifier = aa_modifier,
.exp_modifier = -1.0f .exp_modifier = zone->GetEXPModifierByCharacterID(character_id)
} }
); );
} }
@@ -4288,7 +4288,7 @@ void ZoneDatabase::SetEXPModifierByCharID(
zone_id, zone_id,
instance_version, instance_version,
EXPModifier{ EXPModifier{
.aa_modifier = -1.0f, .aa_modifier = zone->GetAAEXPModifierByCharacterID(character_id),
.exp_modifier = exp_modifier .exp_modifier = exp_modifier
} }
); );