Compare commits

...

17 Commits

Author SHA1 Message Date
Chris Miles 7b914c731b [Release] 22.53.0 (#4395) 2024-06-14 12:44:57 -05:00
Fryguy 7362c0ebb5 [Bug] Anon players should not show in /who all (#4392)
Updated to properly filter anon players from /who all.

The code formatting was very inconsistant and needed cleanup.
2024-06-14 12:39:41 -05:00
Fryguy ae213a4e4b [Rule] Classic Harm Touch Formula (#4394)
* [Rule] Classic Harm Touch Formula

Pre 2007 Harm Touch was handled differently with base harm Touch ( Ability or 2 ranks aa) and Improved Harm Touch AA. It was converted into 10 ranks of Harm Touch -

http://www.tski.co.jp/baldio/patch/20071113.html

It was further refined in 2008 to have a DoT component.

http://www.tski.co.jp/baldio/patch/20080709.html

This rule focuses on the pre 2007 version and allows the damage to properly scale

* Updated logic

* Update per feedback.
2024-06-14 12:28:43 -05:00
Alex King 187288f3aa [Rules] Add Invisible Augment Rules (#4385)
* [Rules] Add Invisible Augment Slot Rule

* Update item_instance.cpp

* Second rule

* Update ruletypes.h
2024-06-14 12:02:21 -05:00
Alex King abc8c3d886 [Cleanup] Remove unused code in emu_constants.h (#4384)
# Description
- Remove unused code that was missed as a result of resolving merge conflicts and this being left behind.
2024-06-14 11:59:13 -05:00
Alex King 0b2493beb8 [Cleanup] Cleanup Object Type Code (#4375)
* [Cleanup] Cleanup Object Type Code

* Move to object.cpp/object.h
2024-06-14 11:58:59 -05:00
JJ 9cebba5911 [Bug Fix] Fix potential trader crash when serialized item not found (#4386) 2024-06-14 11:58:00 -05:00
Fryguy 4478328b2a [Rules] Mend/Sneak allow success tuning (#4390)
MendAlwaysSucceedValue allows you to adjust skill at which mend will always succeed its check.

SneakAlwaysSucceedOver100 allows sneak to always succeed when over skill 100 (Higher skill increases the movement speed).
2024-06-14 11:57:31 -05:00
JJ 55a7e1646d Check that an event actually exists (#4387) 2024-06-14 11:56:33 -05:00
Mitch Freeman b6b8491060 [Bug Fix] Fix for players having empty bazaar window dropdown list, even though trader is tagged as a trader. (#4391)
* Potential fix for players having empty bazaar window dropdown list, even though trader is tagged as a trader.

* Update the truncate of the trader table to avoid inappropriate deletions if an instance of bazaar was started.
2024-06-14 11:53:34 -05:00
Fryguy 850053a136 [Bug] Prevent Resurrection Spells from being resisted (#4393)
* [Bug] Prevent Ressurection Spells from being resisted

Added IsRessurectionSpell(uint16 spell_id) to assist with checking on a spell is a ressurection spell.

This was noticed when Dragons of Norrath launched and the Tier 5 Progression AA provided SPA 180 2% SE_ResistSpellChance

* Helps if I spell it correctly

* Update per feedback
2024-06-14 11:51:33 -05:00
Fryguy 1aa8758b0a [Bug] Escape should put player into SOS if owned. (#4388)
When you escape if you have the Shroud of Stealth bonus (AA, Spell, item) you will go straight into SOS mode.
2024-06-07 13:57:54 -04:00
Alex King b1aa087b9f [Bug Fix] Fix Swarm Pet Damage Messages (#4383) 2024-06-04 18:50:08 -04:00
Alex King 1e57a0372f [Bug Fix] Fix #goto Target (#4382) 2024-06-03 03:02:27 -04:00
Fryguy 9614ea59ec [Rule] Snare Override Movement Bonus (#4381)
* [Rule] Snare Override Movement Bonus

This rule allows snare to override any movement bonuses.

RULE_BOOL(Spells, AllowSnareEffectsOverrideBonus, false, "Enabling will allow snares to override any speed bonuses the entity may have. Default: False")

Default: False

* Rule name

---------

Co-authored-by: Kinglykrab <kinglykrab@gmail.com>
2024-06-02 17:50:41 -04:00
Alex King 7a648cce16 [Cleanup] Cleanup Account Status Code (#4376)
* [Cleanup] Cleanup Account Status Code

* Update emu_constants.cpp

* Update emu_constants.h
2024-06-02 16:40:52 -04:00
Alex King 8640776a21 [Cleanup] Cleanup Body Type Code (#4366)
* [Cleanup] Cleanup Body Type-based Code

* Update bodytypes.cpp

* Final

* Update body_type.cpp

* Cleanup

* Cleanup

* Formatting

---------

Co-authored-by: Akkadius <akkadius1@gmail.com>
2024-06-02 04:25:06 -04:00
61 changed files with 1022 additions and 784 deletions
+29
View File
@@ -1,3 +1,32 @@
## [22.53.0] 6/14/2024
### Bug
* Anon players should not show in /who all ([#4392](https://github.com/EQEmu/Server/pull/4392)) @fryguy503 2024-06-14
* Escape should put player into SOS if owned. ([#4388](https://github.com/EQEmu/Server/pull/4388)) @fryguy503 2024-06-07
* Prevent Resurrection Spells from being resisted ([#4393](https://github.com/EQEmu/Server/pull/4393)) @fryguy503 2024-06-14
### Code
* Cleanup Account Status Code ([#4376](https://github.com/EQEmu/Server/pull/4376)) @Kinglykrab 2024-06-02
* Cleanup Body Type Code ([#4366](https://github.com/EQEmu/Server/pull/4366)) @Kinglykrab 2024-06-02
* Cleanup Object Type Code ([#4375](https://github.com/EQEmu/Server/pull/4375)) @Kinglykrab 2024-06-14
* Remove unused code in emu_constants.h ([#4384](https://github.com/EQEmu/Server/pull/4384)) @Kinglykrab 2024-06-14
### Fixes
* Fix #goto Target ([#4382](https://github.com/EQEmu/Server/pull/4382)) @Kinglykrab 2024-06-03
* Fix Swarm Pet Damage Messages ([#4383](https://github.com/EQEmu/Server/pull/4383)) @Kinglykrab 2024-06-04
* Fix for players having empty bazaar window dropdown list, even though trader is tagged as a trader. ([#4391](https://github.com/EQEmu/Server/pull/4391)) @neckkola 2024-06-14
* Fix potential trader crash when serialized item not found ([#4386](https://github.com/EQEmu/Server/pull/4386)) @joligario 2024-06-14
### Rules
* Add Invisible Augment Rules ([#4385](https://github.com/EQEmu/Server/pull/4385)) @Kinglykrab 2024-06-14
* Classic Harm Touch Formula ([#4394](https://github.com/EQEmu/Server/pull/4394)) @fryguy503 2024-06-14
* Mend/Sneak allow success tuning ([#4390](https://github.com/EQEmu/Server/pull/4390)) @fryguy503 2024-06-14
* Snare Override Movement Bonus ([#4381](https://github.com/EQEmu/Server/pull/4381)) @fryguy503 2024-06-02
## [22.52.0] 6/1/2024
### Code
+1
View File
@@ -3,6 +3,7 @@ CMAKE_MINIMUM_REQUIRED(VERSION 3.12)
SET(common_sources
base_packet.cpp
bazaar.cpp
bodytypes.cpp
classes.cpp
cli/eqemu_command_handler.cpp
compression.cpp
+12
View File
@@ -0,0 +1,12 @@
#include "../common/global_define.h"
#include "../common/bodytypes.h"
std::string BodyType::GetName(uint8 body_type_id)
{
return IsValid(body_type_id) ? body_type_names[body_type_id] : "UNKNOWN BODY TYPE";
}
bool BodyType::IsValid(uint8 body_type_id)
{
return body_type_names.find(body_type_id) != body_type_names.end();
}
+90 -46
View File
@@ -18,52 +18,96 @@
#ifndef BODYTYPES_H
#define BODYTYPES_H
typedef enum {
BT_Humanoid = 1,
BT_Lycanthrope = 2,
BT_Undead = 3,
BT_Giant = 4,
BT_Construct = 5,
BT_Extraplanar = 6,
BT_Magical = 7, //this name might be a bit off,
BT_SummonedUndead = 8,
BT_RaidGiant = 9, //Velious era Raid Giant
BT_RaidColdain = 10, //Velious era Raid Coldain
BT_NoTarget = 11, //no name, can't target this bodytype
BT_Vampire = 12,
BT_Atenha_Ra = 13,
BT_Greater_Akheva = 14,
BT_Khati_Sha = 15,
BT_Seru = 16,
BT_Grieg_Veneficus = 17,
BT_Draz_Nurakk = 18,
BT_Zek = 19, //"creatures from the Plane of War."
BT_Luggald = 20,
BT_Animal = 21,
BT_Insect = 22,
BT_Monster = 23,
BT_Summoned = 24, //Elemental?
BT_Plant = 25,
BT_Dragon = 26,
BT_Summoned2 = 27,
BT_Summoned3 = 28,
BT_Dragon2 = 29, //database data indicates this is a dragon type (kunark and DoN?)
BT_VeliousDragon = 30, //might not be a tight set
BT_Familiar = 31,
BT_Dragon3 = 32,
BT_Boxes = 33,
BT_Muramite = 34, //tribal dudes
// ...
BT_NoTarget2 = 60,
// ...
BT_SwarmPet = 63, //Looks like weapon proc related temp pets and few misc pets, should not be used for checking swarm pets in general.
BT_MonsterSummon = 64,
// 65, trap or effect related?
BT_InvisMan = 66, //no name, seen on 'InvisMan', can be /targeted
BT_Special = 67
} bodyType;
/* bodytypes above 64 make the mob not show up */
#include "types.h"
#include <map>
#include <string>
constexpr int format_as(bodyType type) { return static_cast<int>(type); }
// body types above 64 make the mob invisible
namespace BodyType {
constexpr uint8 Humanoid = 1;
constexpr uint8 Lycanthrope = 2;
constexpr uint8 Undead = 3;
constexpr uint8 Giant = 4;
constexpr uint8 Construct = 5;
constexpr uint8 Extraplanar = 6;
constexpr uint8 Magical = 7; // this name might be a bit off,
constexpr uint8 SummonedUndead = 8;
constexpr uint8 RaidGiant = 9; // Velious era Raid Giant
constexpr uint8 RaidColdain = 10; // Velious era Raid Coldain
constexpr uint8 NoTarget = 11; // no name, can't target this bodytype
constexpr uint8 Vampire = 12;
constexpr uint8 AtenHaRa = 13;
constexpr uint8 GreaterAkheva = 14;
constexpr uint8 KhatiSha = 15;
constexpr uint8 Seru = 16;
constexpr uint8 GriegVeneficus = 17;
constexpr uint8 DrazNurakk = 18;
constexpr uint8 Zek = 19; //"creatures from the Plane of War."
constexpr uint8 Luggald = 20;
constexpr uint8 Animal = 21;
constexpr uint8 Insect = 22;
constexpr uint8 Monster = 23;
constexpr uint8 Summoned = 24; // Elemental?
constexpr uint8 Plant = 25;
constexpr uint8 Dragon = 26;
constexpr uint8 Summoned2 = 27;
constexpr uint8 Summoned3 = 28;
constexpr uint8 Dragon2 = 29; // database data indicates this is a dragon type (Kunark and DoN?)
constexpr uint8 VeliousDragon = 30; // might not be a tight set
constexpr uint8 Familiar = 31;
constexpr uint8 Dragon3 = 32;
constexpr uint8 Boxes = 33;
constexpr uint8 Muramite = 34; // tribal dudes
constexpr uint8 NoTarget2 = 60;
constexpr uint8 SwarmPet = 63; // Looks like weapon proc related temp pets and few misc pets, should not be used for checking swarm pets in general.
constexpr uint8 MonsterSummon = 64;
constexpr uint8 InvisibleMan = 66; // no name, seen on 'InvisMan', can be /targeted
constexpr uint8 Special = 67;
std::string GetName(uint8 body_type_id);
bool IsValid(uint8 body_type_id);
}
static std::map<uint8, std::string> body_type_names = {
{ BodyType::Humanoid, "Humanoid" },
{ BodyType::Lycanthrope, "Lycanthrope" },
{ BodyType::Undead, "Undead" },
{ BodyType::Giant, "Giant" },
{ BodyType::Construct, "Construct" },
{ BodyType::Extraplanar, "Extraplanar" },
{ BodyType::Magical, "Magical" },
{ BodyType::SummonedUndead, "Summoned Undead" },
{ BodyType::RaidGiant, "Raid Giant" },
{ BodyType::RaidColdain, "Raid Coldain" },
{ BodyType::NoTarget, "Untargetable" },
{ BodyType::Vampire, "Vampire" },
{ BodyType::AtenHaRa, "Aten Ha Ra" },
{ BodyType::GreaterAkheva, "Greater Akheva" },
{ BodyType::KhatiSha, "Khati Sha" },
{ BodyType::Seru, "Seru" },
{ BodyType::GriegVeneficus, "Grieg Veneficus" },
{ BodyType::DrazNurakk, "Draz Nurakk" },
{ BodyType::Zek, "Zek" },
{ BodyType::Luggald, "Luggald" },
{ BodyType::Animal, "Animal" },
{ BodyType::Insect, "Insect" },
{ BodyType::Monster, "Monster" },
{ BodyType::Summoned, "Summoned" },
{ BodyType::Plant, "Plant" },
{ BodyType::Dragon, "Dragon" },
{ BodyType::Summoned2, "Summoned 2" },
{ BodyType::Summoned3, "Summoned 3" },
{ BodyType::Dragon2, "Dragon 2" },
{ BodyType::VeliousDragon, "Velious Dragon" },
{ BodyType::Familiar, "Familiar" },
{ BodyType::Dragon3, "Dragon 3" },
{ BodyType::Boxes, "Boxes" },
{ BodyType::Muramite, "Muramite" },
{ BodyType::NoTarget2, "Untargetable 2" },
{ BodyType::SwarmPet, "Swarm Pet" },
{ BodyType::MonsterSummon, "Monster Summon" },
{ BodyType::InvisibleMan, "Invisible Man" },
{ BodyType::Special, "Special" },
};
#endif
+15 -174
View File
@@ -206,102 +206,6 @@ std::string EQ::constants::GetFlyModeName(int8 flymode_id)
return EQ::constants::GetFlyModeMap().find(flymode_id)->second;
}
const std::map<bodyType, std::string>& EQ::constants::GetBodyTypeMap()
{
static const std::map<bodyType, std::string> bodytype_map = {
{ BT_Humanoid, "Humanoid" },
{ BT_Lycanthrope, "Lycanthrope" },
{ BT_Undead, "Undead" },
{ BT_Giant, "Giant" },
{ BT_Construct, "Construct" },
{ BT_Extraplanar, "Extraplanar" },
{ BT_Magical, "Magical" },
{ BT_SummonedUndead, "Summoned Undead" },
{ BT_RaidGiant, "Raid Giant" },
{ BT_RaidColdain, "Raid Coldain" },
{ BT_NoTarget, "Untargetable" },
{ BT_Vampire, "Vampire" },
{ BT_Atenha_Ra, "Aten Ha Ra" },
{ BT_Greater_Akheva, "Greater Akheva" },
{ BT_Khati_Sha, "Khati Sha" },
{ BT_Seru, "Seru" },
{ BT_Grieg_Veneficus, "Grieg Veneficus" },
{ BT_Draz_Nurakk, "Draz Nurakk" },
{ BT_Zek, "Zek" },
{ BT_Luggald, "Luggald" },
{ BT_Animal, "Animal" },
{ BT_Insect, "Insect" },
{ BT_Monster, "Monster" },
{ BT_Summoned, "Summoned" },
{ BT_Plant, "Plant" },
{ BT_Dragon, "Dragon" },
{ BT_Summoned2, "Summoned 2" },
{ BT_Summoned3, "Summoned 3" },
{ BT_Dragon2, "Dragon 2" },
{ BT_VeliousDragon, "Velious Dragon" },
{ BT_Familiar, "Familiar" },
{ BT_Dragon3, "Dragon 3" },
{ BT_Boxes, "Boxes" },
{ BT_Muramite, "Muramite" },
{ BT_NoTarget2, "Untargetable 2" },
{ BT_SwarmPet, "Swarm Pet" },
{ BT_MonsterSummon, "Monster Summon" },
{ BT_InvisMan, "Invisible Man" },
{ BT_Special, "Special" },
};
return bodytype_map;
}
std::string EQ::constants::GetBodyTypeName(bodyType bodytype_id)
{
if (EQ::constants::GetBodyTypeMap().find(bodytype_id) != EQ::constants::GetBodyTypeMap().end()) {
return EQ::constants::GetBodyTypeMap().find(bodytype_id)->second;
}
return std::string();
}
const std::map<uint8, std::string>& EQ::constants::GetAccountStatusMap()
{
static const std::map<uint8, std::string> account_status_map = {
{ AccountStatus::Player, "Player" },
{ AccountStatus::Steward, "Steward" },
{ AccountStatus::ApprenticeGuide, "Apprentice Guide" },
{ AccountStatus::Guide, "Guide" },
{ AccountStatus::QuestTroupe, "Quest Troupe" },
{ AccountStatus::SeniorGuide, "Senior Guide" },
{ AccountStatus::GMTester, "GM Tester" },
{ AccountStatus::EQSupport, "EQ Support" },
{ AccountStatus::GMStaff, "GM Staff" },
{ AccountStatus::GMAdmin, "GM Admin" },
{ AccountStatus::GMLeadAdmin, "GM Lead Admin" },
{ AccountStatus::QuestMaster, "Quest Master" },
{ AccountStatus::GMAreas, "GM Areas" },
{ AccountStatus::GMCoder, "GM Coder" },
{ AccountStatus::GMMgmt, "GM Mgmt" },
{ AccountStatus::GMImpossible, "GM Impossible" },
{ AccountStatus::Max, "GM Max" }
};
return account_status_map;
}
std::string EQ::constants::GetAccountStatusName(uint8 account_status)
{
for (
auto status_level = EQ::constants::GetAccountStatusMap().rbegin();
status_level != EQ::constants::GetAccountStatusMap().rend();
++status_level
) {
if (account_status >= status_level->first) {
return status_level->second;
}
}
return std::string();
}
const std::map<uint8, std::string>& EQ::constants::GetConsiderLevelMap()
{
static const std::map<uint8, std::string> consider_level_map = {
@@ -392,84 +296,6 @@ std::string EQ::constants::GetSpawnAnimationName(uint8 animation_id)
return EQ::constants::GetSpawnAnimationMap().find(animation_id)->second;
}
const std::map<int, std::string>& EQ::constants::GetObjectTypeMap()
{
static const std::map<int, std::string> object_type_map = {
{ ObjectTypes::SmallBag, "Small Bag" },
{ ObjectTypes::LargeBag, "Large Bag" },
{ ObjectTypes::Quiver, "Quiver" },
{ ObjectTypes::BeltPouch, "Belt Pouch" },
{ ObjectTypes::WristPouch, "Wrist Pouch" },
{ ObjectTypes::Backpack, "Backpack" },
{ ObjectTypes::SmallChest, "Small Chest" },
{ ObjectTypes::LargeChest, "Large Chest" },
{ ObjectTypes::Bandolier, "Bandolier" },
{ ObjectTypes::Medicine, "Medicine" },
{ ObjectTypes::Tinkering, "Tinkering" },
{ ObjectTypes::Lexicon, "Lexicon" },
{ ObjectTypes::PoisonMaking, "Mortar and Pestle" },
{ ObjectTypes::Quest, "Quest" },
{ ObjectTypes::MixingBowl, "Mixing Bowl" },
{ ObjectTypes::Baking, "Baking" },
{ ObjectTypes::Tailoring, "Tailoring" },
{ ObjectTypes::Blacksmithing, "Blacksmithing" },
{ ObjectTypes::Fletching, "Fletching" },
{ ObjectTypes::Brewing, "Brewing" },
{ ObjectTypes::JewelryMaking, "Jewelry Making" },
{ ObjectTypes::Pottery, "Pottery" },
{ ObjectTypes::Kiln, "Kiln" },
{ ObjectTypes::KeyMaker, "Key Maker" },
{ ObjectTypes::ResearchWIZ, "Lexicon" },
{ ObjectTypes::ResearchMAG, "Lexicon" },
{ ObjectTypes::ResearchNEC, "Lexicon" },
{ ObjectTypes::ResearchENC, "Lexicon" },
{ ObjectTypes::Unknown, "Unknown" },
{ ObjectTypes::ResearchPractice, "Lexicon" },
{ ObjectTypes::Alchemy, "Alchemy" },
{ ObjectTypes::HighElfForge, "High Elf Forge" },
{ ObjectTypes::DarkElfForge, "Dark Elf Forge" },
{ ObjectTypes::OgreForge, "Ogre Forge" },
{ ObjectTypes::DwarfForge, "Dwarf Forge" },
{ ObjectTypes::GnomeForge, "Gnome Forge" },
{ ObjectTypes::BarbarianForge, "Barbarian Forge" },
{ ObjectTypes::IksarForge, "Iksar Forge" },
{ ObjectTypes::HumanForgeOne, "Human Forge" },
{ ObjectTypes::HumanForgeTwo, "Human Forge" },
{ ObjectTypes::HalflingTailoringOne, "Halfling Tailoring" },
{ ObjectTypes::HalflingTailoringTwo, "Halfling Tailoring" },
{ ObjectTypes::EruditeTailoring, "Erudite Tailoring" },
{ ObjectTypes::WoodElfTailoring, "Wood Elf Tailoring" },
{ ObjectTypes::WoodElfFletching, "Wood Elf Fletching" },
{ ObjectTypes::IksarPottery, "Iksar Pottery" },
{ ObjectTypes::Fishing, "Fishing" },
{ ObjectTypes::TrollForge, "Troll Forge" },
{ ObjectTypes::WoodElfForge, "Wood Elf Forge" },
{ ObjectTypes::HalflingForge, "Halfling Forge" },
{ ObjectTypes::EruditeForge, "Erudite Forge" },
{ ObjectTypes::Merchant, "Merchant" },
{ ObjectTypes::FroglokForge, "Froglok Forge" },
{ ObjectTypes::Augmenter, "Augmenter" },
{ ObjectTypes::Churn, "Churn" },
{ ObjectTypes::TransformationMold, "Transformation Mold" },
{ ObjectTypes::DetransformationMold, "Detransformation Mold" },
{ ObjectTypes::Unattuner, "Unattuner" },
{ ObjectTypes::TradeskillBag, "Tradeskill Bag" },
{ ObjectTypes::CollectibleBag, "Collectible Bag" },
{ ObjectTypes::NoDeposit, "No Deposit" }
};
return object_type_map;
}
std::string EQ::constants::GetObjectTypeName(int object_type)
{
if (!EQ::ValueWithin(object_type, ObjectTypes::SmallBag, ObjectTypes::NoDeposit)) {
return std::string();
}
return EQ::constants::GetObjectTypeMap().find(object_type)->second;
}
const std::map<uint8, std::string> &EQ::constants::GetWeatherTypeMap()
{
static const std::map<uint8, std::string> weather_type_map = {
@@ -629,6 +455,21 @@ std::string EQ::constants::GetConsiderColorName(uint32 consider_color)
return c != EQ::constants::GetConsiderColorMap().end() ? c->second : std::string();
}
std::string AccountStatus::GetName(uint8 account_status)
{
for (
auto e = account_status_names.rbegin();
e != account_status_names.rend();
++e
) {
if (account_status >= e->first) {
return e->second;
}
}
return "UNKNOWN ACCOUNT STATUS";
}
std::string ComparisonType::GetName(uint8 type)
{
return IsValid(type) ? comparison_types[type] : "UNKNOWN COMPARISON TYPE";
+42 -94
View File
@@ -26,6 +26,48 @@
#include <string.h>
namespace AccountStatus {
constexpr uint8 Player = 0;
constexpr uint8 Steward = 10;
constexpr uint8 ApprenticeGuide = 20;
constexpr uint8 Guide = 50;
constexpr uint8 QuestTroupe = 80;
constexpr uint8 SeniorGuide = 81;
constexpr uint8 GMTester = 85;
constexpr uint8 EQSupport = 90;
constexpr uint8 GMStaff = 95;
constexpr uint8 GMAdmin = 100;
constexpr uint8 GMLeadAdmin = 150;
constexpr uint8 QuestMaster = 160;
constexpr uint8 GMAreas = 170;
constexpr uint8 GMCoder = 180;
constexpr uint8 GMMgmt = 200;
constexpr uint8 GMImpossible = 250;
constexpr uint8 Max = 255;
std::string GetName(uint8 account_status);
}
static std::map<uint8, std::string> account_status_names = {
{ AccountStatus::Player, "Player" },
{ AccountStatus::Steward, "Steward" },
{ AccountStatus::ApprenticeGuide, "Apprentice Guide" },
{ AccountStatus::Guide, "Guide" },
{ AccountStatus::QuestTroupe, "Quest Troupe" },
{ AccountStatus::SeniorGuide, "Senior Guide" },
{ AccountStatus::GMTester, "GM Tester" },
{ AccountStatus::EQSupport, "EQ Support" },
{ AccountStatus::GMStaff, "GM Staff" },
{ AccountStatus::GMAdmin, "GM Admin" },
{ AccountStatus::GMLeadAdmin, "GM Lead Admin" },
{ AccountStatus::QuestMaster, "Quest Master" },
{ AccountStatus::GMAreas, "GM Areas" },
{ AccountStatus::GMCoder, "GM Coder" },
{ AccountStatus::GMMgmt, "GM Mgmt" },
{ AccountStatus::GMImpossible, "GM Impossible" },
{ AccountStatus::Max, "GM Max" }
};
namespace ComparisonType {
constexpr uint8 Equal = 0;
constexpr uint8 NotEqual = 1;
@@ -55,7 +97,6 @@ static std::map<uint8, std::string> comparison_types = {
{ ComparisonType::NotBetween, "Not Between" },
};
// local definitions are the result of using hybrid-client or server-only values and methods
namespace EQ
{
@@ -296,70 +337,6 @@ namespace EQ
Looting
};
enum ObjectTypes : int {
SmallBag,
LargeBag,
Quiver,
BeltPouch,
WristPouch,
Backpack,
SmallChest,
LargeChest,
Bandolier,
Medicine,
Tinkering,
Lexicon,
PoisonMaking,
Quest,
MixingBowl,
Baking,
Tailoring,
Blacksmithing,
Fletching,
Brewing,
JewelryMaking,
Pottery,
Kiln,
KeyMaker,
ResearchWIZ,
ResearchMAG,
ResearchNEC,
ResearchENC,
Unknown,
ResearchPractice,
Alchemy,
HighElfForge,
DarkElfForge,
OgreForge,
DwarfForge,
GnomeForge,
BarbarianForge,
IksarForge,
HumanForgeOne,
HumanForgeTwo,
HalflingTailoringOne,
HalflingTailoringTwo,
EruditeTailoring,
WoodElfTailoring,
WoodElfFletching,
IksarPottery,
Fishing,
TrollForge,
WoodElfForge,
HalflingForge,
EruditeForge,
Merchant,
FroglokForge,
Augmenter,
Churn,
TransformationMold,
DetransformationMold,
Unattuner,
TradeskillBag,
CollectibleBag,
NoDeposit
};
enum WeatherTypes : uint8 {
None,
Raining,
@@ -397,12 +374,6 @@ namespace EQ
extern const std::map<int8, std::string>& GetFlyModeMap();
std::string GetFlyModeName(int8 flymode_id);
extern const std::map<bodyType, std::string>& GetBodyTypeMap();
std::string GetBodyTypeName(bodyType bodytype_id);
extern const std::map<uint8, std::string>& GetAccountStatusMap();
std::string GetAccountStatusName(uint8 account_status);
extern const std::map<uint8, std::string>& GetConsiderLevelMap();
std::string GetConsiderLevelName(uint8 consider_level);
@@ -415,9 +386,6 @@ namespace EQ
extern const std::map<uint8, std::string>& GetSpawnAnimationMap();
std::string GetSpawnAnimationName(uint8 animation_id);
extern const std::map<int, std::string>& GetObjectTypeMap();
std::string GetObjectTypeName(int object_type);
extern const std::map<uint8, std::string>& GetWeatherTypeMap();
std::string GetWeatherTypeName(uint8 weather_type);
@@ -512,26 +480,6 @@ enum ServerLockType : int {
Unlock
};
enum AccountStatus : uint8 {
Player = 0,
Steward = 10,
ApprenticeGuide = 20,
Guide = 50,
QuestTroupe = 80,
SeniorGuide = 81,
GMTester = 85,
EQSupport = 90,
GMStaff = 95,
GMAdmin = 100,
GMLeadAdmin = 150,
QuestMaster = 160,
GMAreas = 170,
GMCoder = 180,
GMMgmt = 200,
GMImpossible = 250,
Max = 255
};
enum Invisibility : uint8 {
Visible,
Invisible,
+15 -28
View File
@@ -303,47 +303,34 @@ int8 EQ::ItemInstance::AvailableAugmentSlot(int32 augment_type) const
return INVALID_INDEX;
}
auto i = invaug::SOCKET_BEGIN;
for (; i <= invaug::SOCKET_END; ++i) {
if (GetItem(i)) {
continue;
}
if (
augment_type == -1 ||
(
m_item->AugSlotType[i] &&
((1 << (m_item->AugSlotType[i] - 1)) & augment_type)
)
) {
break;
for (int16 slot_id = invaug::SOCKET_BEGIN; slot_id <= invaug::SOCKET_END; ++slot_id) {
if (IsAugmentSlotAvailable(augment_type, slot_id)) {
return slot_id;
}
}
return (i <= invaug::SOCKET_END) ? i : INVALID_INDEX;
return INVALID_INDEX;
}
bool EQ::ItemInstance::IsAugmentSlotAvailable(int32 augment_type, uint8 slot) const
{
if (!m_item || !m_item->IsClassCommon()) {
if (!m_item || !m_item->IsClassCommon() || GetItem(slot)) {
return false;
}
if (
return (
(
!GetItem(slot) &&
m_item->AugSlotVisible[slot]
augment_type == -1 ||
(
m_item->AugSlotType[slot] &&
((1 << (m_item->AugSlotType[slot] - 1)) & augment_type)
)
) &&
augment_type == -1 ||
(
m_item->AugSlotType[slot] &&
((1 << (m_item->AugSlotType[slot] - 1)) & augment_type)
RuleB(Items, AugmentItemAllowInvisibleAugments) ||
m_item->AugSlotVisible[slot]
)
) {
return true;
}
return false;
);
}
// Retrieve item inside container
@@ -1292,7 +1279,7 @@ int EQ::ItemInstance::GetItemBaneDamageRace(bool augments) const
return race;
}
int EQ::ItemInstance::GetItemBaneDamageBody(bodyType against, bool augments) const
int EQ::ItemInstance::GetItemBaneDamageBody(uint8 against, bool augments) const
{
int64 damage = 0;
const auto item = GetItem();
+1 -1
View File
@@ -265,7 +265,7 @@ namespace EQ
// these two are just quick checks
int GetItemBaneDamageBody(bool augments = false) const;
int GetItemBaneDamageRace(bool augments = false) const;
int GetItemBaneDamageBody(bodyType against, bool augments = false) const;
int GetItemBaneDamageBody(uint8 against, bool augments = false) const;
int GetItemBaneDamageRace(uint16 against, bool augments = false) const;
int GetItemMagical(bool augments = false) const;
int GetItemHP(bool augments = false) const;
+1 -1
View File
@@ -542,8 +542,8 @@ namespace RoF2
LogTrading(
"(RoF2) AddTraderToBazaarWindow action <green>[{}] trader_id <green>[{}] entity_id <green>[{}] zone_id <green>[{}]",
eq->action,
eq->entity_id,
eq->trader_id,
eq->entity_id,
eq->zone_id
);
dest->FastQueuePacket(&outapp);
@@ -49,6 +49,7 @@ public:
// these are the base definitions for command_subsettings and can be over-ridden by the database
std::vector<CommandSubsettingsRepository::CommandSubsettings> static_records = {
{.parent_command = "find", .sub_command = "aa", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findaa"},
{.parent_command = "find", .sub_command = "body_type", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findbodytype"},
{.parent_command = "find", .sub_command = "bug_category", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findbugcategory"},
{.parent_command = "find", .sub_command = "character", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findcharacter"},
{.parent_command = "find", .sub_command = "class", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findclass"},
@@ -60,6 +61,7 @@ public:
{.parent_command = "find", .sub_command = "item", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "fi|finditem|itemsearch"},
{.parent_command = "find", .sub_command = "language", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findlanguage"},
{.parent_command = "find", .sub_command = "npc_type", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "fn|findnpc|findnpctype"},
{.parent_command = "find", .sub_command = "object_type", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findobjecttype"},
{.parent_command = "find", .sub_command = "race", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findrace"},
{.parent_command = "find", .sub_command = "recipe", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findrecipe"},
{.parent_command = "find", .sub_command = "skill", .access_level = AccountStatus::QuestTroupe, .top_level_aliases = "findskill"},
+6
View File
@@ -226,6 +226,8 @@ RULE_INT(Character, ClearXTargetDelay, 10, "Seconds between uses of the #clearxt
RULE_BOOL(Character, PreventMountsFromZoning, false, "Enable to prevent mounts from zoning - Prior to December 15, 2004 this is enabled.")
RULE_BOOL(Character, GroupInvitesRequireTarget, false, "Enable to require players to have invitee on target (Disables /invite name) - Classic Style")
RULE_BOOL(Character, PlayerTradingLoreFeedback, true, "If enabled, during a player to player trade, if lore items exist, it will output which items.")
RULE_INT(Character, MendAlwaysSucceedValue, 199, "Value at which mend will always succeed its skill check. Default: 199")
RULE_BOOL(Character, SneakAlwaysSucceedOver100, false, "When sneak skill is over 100, always succeed sneak/hide. Default: false")
RULE_CATEGORY_END()
RULE_CATEGORY(Mercs)
@@ -503,9 +505,11 @@ RULE_BOOL(Spells, RequireMnemonicRetention, true, "Enabling will require spell s
RULE_BOOL(Spells, EvacClearCharmPet, false, "Enable to have evac in zone clear charm from charm pets and detach buffs.")
RULE_BOOL(Spells, ManaTapsRequireNPCMana, false, "Enabling will require target to have mana to tap. Default off as many npc's are caster class with 0 mana and need fixed.")
RULE_INT(Spells, HarmTouchCritRatio, 200, "Harmtouch crit bonus, on top of BaseCritRatio")
RULE_BOOL(Spells, UseClassicHarmTouchDamage, false, "Use pre 2007 Harm Touch calculations - Default: False")
RULE_BOOL(Spells, UseClassicSpellFocus, false, "Enabling will tell the server to handle random focus damage as classic spell imports lack the limit values.")
RULE_BOOL(Spells, ManaTapsOnAnyClass, false, "Enabling this will allow you to cast mana taps on any class, this will bypass ManaTapsRequireNPCMana rule.")
RULE_INT(Spells, HealAmountMessageFilterThreshold, 100, "Lifetaps below this threshold will not have a message sent to the client (Heal will still process) 0 to Disable.")
RULE_BOOL(Spells, SnareOverridesSpeedBonuses, false, "Enabling will allow snares to override any speed bonuses the entity may have. Default: False")
RULE_CATEGORY_END()
RULE_CATEGORY(Combat)
@@ -993,6 +997,8 @@ RULE_BOOL(Items, DisableNoRent, false, "Enable this to disable No Rent Items")
RULE_BOOL(Items, DisableNoTransfer, false, "Enable this to disable No Transfer Items")
RULE_BOOL(Items, DisablePotionBelt, false, "Enable this to disable Potion Belt Items")
RULE_BOOL(Items, DisableSpellFocusEffects, false, "Enable this to disable Spell Focus Effects on Items")
RULE_BOOL(Items, SummonItemAllowInvisibleAugments, false, "Enable this to allow augments to be put in invisible augment slots of items in Client::SummonItem")
RULE_BOOL(Items, AugmentItemAllowInvisibleAugments, false, "Enable this to allow augments to be put in invisible augment slots by players")
RULE_CATEGORY_END()
RULE_CATEGORY(Parcel)
+10
View File
@@ -431,6 +431,16 @@ bool IsCharmSpell(uint16 spell_id)
return IsEffectInSpell(spell_id, SE_Charm);
}
bool IsResurrectionSicknessSpell(uint16 spell_id) {
return (
spell_id == SPELL_RESURRECTION_SICKNESS ||
spell_id == SPELL_RESURRECTION_SICKNESS2 ||
spell_id == SPELL_RESURRECTION_SICKNESS3 ||
spell_id == SPELL_RESURRECTION_SICKNESS4 ||
spell_id == SPELL_REVIVAL_SICKNESS
);
}
bool IsBlindSpell(uint16 spell_id)
{
return IsEffectInSpell(spell_id, SE_Blind);
+1
View File
@@ -1522,6 +1522,7 @@ bool IsSummonPetSpell(uint16 spell_id);
bool IsSummonPCSpell(uint16 spell_id);
bool IsPetSpell(uint16 spell_id);
bool IsCharmSpell(uint16 spell_id);
bool IsResurrectionSicknessSpell(uint16 spell_id);
bool IsBlindSpell(uint16 spell_id);
bool IsHealthSpell(uint16 spell_id);
bool IsCastTimeReductionSpell(uint16 spell_id);
+1 -1
View File
@@ -25,7 +25,7 @@
// Build variables
// these get injected during the build pipeline
#define CURRENT_VERSION "22.52.0-dev" // always append -dev to the current version for custom-builds
#define CURRENT_VERSION "22.53.0-dev" // always append -dev to the current version for custom-builds
#define LOGIN_VERSION "0.8.0"
#define COMPILE_DATE __DATE__
#define COMPILE_TIME __TIME__
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "eqemu-server",
"version": "22.52.0",
"version": "22.53.0",
"repository": {
"type": "git",
"url": "https://github.com/EQEmu/Server.git"
+279 -234
View File
@@ -528,276 +528,321 @@ void ClientList::SendOnlineGuildMembers(uint32 FromID, uint32 GuildID)
safe_delete(pack);
}
void ClientList::SendWhoAll(uint32 fromid,const char* to, int16 admin, Who_All_Struct* whom, WorldTCPConnection* connection) {
try{
LinkedListIterator<ClientListEntry*> iterator(clientlist);
LinkedListIterator<ClientListEntry*> countclients(clientlist);
ClientListEntry* cle = 0;
ClientListEntry* countcle = 0;
//char tmpgm[25] = "";
//char accinfo[150] = "";
char line[300] = "";
//char tmpguild[50] = "";
//char LFG[10] = "";
//uint32 x = 0;
int whomlen = 0;
if (whom) {
// fixes for client converting some queries into a race query instead of zone
if (whom->wrace == 221) {
whom->wrace = 0xFFFF;
strcpy(whom->whom, "scarlet");
}
if (whom->wrace == 327) {
whom->wrace = 0xFFFF;
strcpy(whom->whom, "crystal");
}
if (whom->wrace == 103) {
whom->wrace = 0xFFFF;
strcpy(whom->whom, "kedge");
}
if (whom->wrace == 230) {
whom->wrace = 0xFFFF;
strcpy(whom->whom, "akheva");
}
if (whom->wrace == 229) {
whom->wrace = 0xFFFF;
strcpy(whom->whom, "netherbian");
}
try {
LinkedListIterator<ClientListEntry*> iterator(clientlist);
LinkedListIterator<ClientListEntry*> countclients(clientlist);
ClientListEntry* cle = 0;
ClientListEntry* countcle = 0;
//char tmpgm[25] = "";
//char accinfo[150] = "";
char line[300] = "";
//char tmpguild[50] = "";
//char LFG[10] = "";
//uint32 x = 0;
int whomlen = 0;
whomlen = strlen(whom->whom);
if(whom->wrace == 0x001A) // 0x001A is the old Froglok race number and is sent by the client for /who all froglok
whom->wrace = FROGLOK; // This is what EQEmu uses for the Froglok Race number.
}
uint32 totalusers=0;
uint32 totallength=0;
countclients.Reset();
while(countclients.MoreElements()){
countcle = countclients.GetData();
const char* tmpZone = ZoneName(countcle->zone());
if (
(countcle->Online() >= CLE_Status::Zoning) &&
(!countcle->GetGM() || countcle->Anon() != 1 || admin >= countcle->Admin()) &&
(whom == 0 || (
((countcle->Admin() >= AccountStatus::QuestTroupe && countcle->GetGM()) || whom->gmlookup == 0xFFFF) &&
(whom->lvllow == 0xFFFF || (countcle->level() >= whom->lvllow && countcle->level() <= whom->lvlhigh && (countcle->Anon()==0 || admin > countcle->Admin()))) &&
(whom->wclass == 0xFFFF || (countcle->class_() == whom->wclass && (countcle->Anon()==0 || admin > countcle->Admin()))) &&
(whom->wrace == 0xFFFF || (countcle->race() == whom->wrace && (countcle->Anon()==0 || admin > countcle->Admin()))) &&
(whomlen == 0 || (
(tmpZone != 0 && strncasecmp(tmpZone, whom->whom, whomlen) == 0) ||
strncasecmp(countcle->name(),whom->whom, whomlen) == 0 ||
(strncasecmp(guild_mgr.GetGuildName(countcle->GuildID()), whom->whom, whomlen) == 0) ||
(admin >= AccountStatus::GMAdmin && strncasecmp(countcle->AccountName(), whom->whom, whomlen) == 0)
))
))
) {
if((countcle->Anon()>0 && admin >= countcle->Admin() && admin > AccountStatus::Player) || countcle->Anon()==0 ){
totalusers++;
if(totalusers<=20 || admin >= AccountStatus::GMAdmin)
totallength=totallength+strlen(countcle->name())+strlen(countcle->AccountName())+strlen(guild_mgr.GetGuildName(countcle->GuildID()))+5;
if (whom) {
// fixes for client converting some queries into a race query instead of zone
if (whom->wrace == 221) {
whom->wrace = 0xFFFF;
strcpy(whom->whom, "scarlet");
}
else if((countcle->Anon()>0 && admin<=countcle->Admin()) || (countcle->Anon()==0 && !countcle->GetGM())) {
totalusers++;
if(totalusers<=20 || admin >= AccountStatus::GMAdmin)
totallength=totallength+strlen(countcle->name())+strlen(guild_mgr.GetGuildName(countcle->GuildID()))+5;
if (whom->wrace == 327) {
whom->wrace = 0xFFFF;
strcpy(whom->whom, "crystal");
}
if (whom->wrace == 103) {
whom->wrace = 0xFFFF;
strcpy(whom->whom, "kedge");
}
if (whom->wrace == 230) {
whom->wrace = 0xFFFF;
strcpy(whom->whom, "akheva");
}
if (whom->wrace == 229) {
whom->wrace = 0xFFFF;
strcpy(whom->whom, "netherbian");
}
whomlen = strlen(whom->whom);
if (whom->wrace == 0x001A) { // 0x001A is the old Froglok race number and is sent by the client for /who all froglok
whom->wrace = FROGLOK; // This is what EQEmu uses for the Froglok Race number.
}
}
countclients.Advance();
}
uint32 plid=fromid;
uint32 playerineqstring=5001;
const char line2[]="---------------------------";
uint8 unknown35=0x0A;
uint32 unknown36=0;
uint32 playersinzonestring=5028;
if(totalusers>20 && admin<AccountStatus::GMAdmin){
totalusers=20;
playersinzonestring=5033;
}
else if(totalusers>1)
playersinzonestring=5036;
uint32 unknown44[2];
unknown44[0]=0;
unknown44[1]=0;
uint32 unknown52=totalusers;
uint32 unknown56=1;
auto pack2 = new ServerPacket(ServerOP_WhoAllReply, 64 + totallength + (49 * totalusers));
memset(pack2->pBuffer,0,pack2->size);
uchar *buffer=pack2->pBuffer;
uchar *bufptr=buffer;
//memset(buffer,0,pack2->size);
memcpy(bufptr,&plid, sizeof(uint32));
bufptr+=sizeof(uint32);
memcpy(bufptr,&playerineqstring, sizeof(uint32));
bufptr+=sizeof(uint32);
memcpy(bufptr,&line2, strlen(line2));
bufptr+=strlen(line2);
memcpy(bufptr,&unknown35, sizeof(uint8));
bufptr+=sizeof(uint8);
memcpy(bufptr,&unknown36, sizeof(uint32));
bufptr+=sizeof(uint32);
memcpy(bufptr,&playersinzonestring, sizeof(uint32));
bufptr+=sizeof(uint32);
memcpy(bufptr,&unknown44[0], sizeof(uint32));
bufptr+=sizeof(uint32);
memcpy(bufptr,&unknown44[1], sizeof(uint32));
bufptr+=sizeof(uint32);
memcpy(bufptr,&unknown52, sizeof(uint32));
bufptr+=sizeof(uint32);
memcpy(bufptr,&unknown56, sizeof(uint32));
bufptr+=sizeof(uint32);
memcpy(bufptr,&totalusers, sizeof(uint32));
bufptr+=sizeof(uint32);
iterator.Reset();
int idx=-1;
while(iterator.MoreElements()) {
cle = iterator.GetData();
const char* tmpZone = ZoneName(cle->zone());
uint32 totalusers=0;
uint32 totallength=0;
countclients.Reset();
while (countclients.MoreElements()) {
countcle = countclients.GetData();
const char* tmpZone = ZoneName(countcle->zone());
if (
(countcle->Online() >= CLE_Status::Zoning) &&
(!countcle->GetGM() || countcle->Anon() != 1 || admin >= countcle->Admin()) &&
(whom == 0 || (
((countcle->Admin() >= AccountStatus::QuestTroupe && countcle->GetGM()) || whom->gmlookup == 0xFFFF) &&
(whom->lvllow == 0xFFFF ||
(countcle->level() >= whom->lvllow && countcle->level() <= whom->lvlhigh &&
(countcle->Anon() == 0 || admin > countcle->Admin()))) &&
(whom->wclass == 0xFFFF || (countcle->class_() == whom->wclass &&
(countcle->Anon() == 0 || admin > countcle->Admin()))) &&
(whom->wrace == 0xFFFF ||
(countcle->race() == whom->wrace && (countcle->Anon() == 0 || admin > countcle->Admin()))) &&
(whomlen == 0 || (
(tmpZone != 0 && strncasecmp(tmpZone, whom->whom, whomlen) == 0) ||
strncasecmp(countcle->name(),whom->whom, whomlen) == 0 ||
(strncasecmp(guild_mgr.GetGuildName(countcle->GuildID()), whom->whom, whomlen) == 0) ||
(admin >= AccountStatus::GMAdmin && strncasecmp(countcle->AccountName(), whom->whom, whomlen) == 0)
))
))
) {
// these blocks can all be condensed but it's simpler to conceptualize this way
if ((countcle->Anon()>0 && admin >= countcle->Admin() && admin > AccountStatus::Player) || countcle->Anon()==0 ) {
totalusers++;
if (totalusers<=20 || admin >= AccountStatus::GMAdmin) {
totallength = totallength + strlen(countcle->name()) + strlen(countcle->AccountName()) +
strlen(guild_mgr.GetGuildName(countcle->GuildID())) + 5;
}
} else if (((countcle->Anon() == 1 && admin <= countcle->Admin()) && whomlen != 0 &&
strncasecmp(countcle->name(), whom->whom, whomlen) == 0)) {
totalusers++;
if (totalusers <= 20 || admin >= AccountStatus::GMAdmin) {
totallength = totallength + strlen(countcle->name()) + strlen(countcle->AccountName()) +
strlen(guild_mgr.GetGuildName(countcle->GuildID())) + 5;
}
} else if (((countcle->Anon() == 2 && admin <= countcle->Admin()) && whomlen != 0 &&
(strncasecmp(countcle->name(), whom->whom, whomlen) == 0 ||
strncasecmp(guild_mgr.GetGuildName(countcle->GuildID()), whom->whom, whomlen) == 0))) {
totalusers++;
if (totalusers <= 20 || admin >= AccountStatus::GMAdmin) {
totallength = totallength + strlen(countcle->name()) + strlen(countcle->AccountName()) +
strlen(guild_mgr.GetGuildName(countcle->GuildID())) + 5;
}
}
}
countclients.Advance();
}
if (
(cle->Online() >= CLE_Status::Zoning) &&
(!cle->GetGM() || cle->Anon() != 1 || admin >= cle->Admin()) &&
(whom == 0 || (
((cle->Admin() >= AccountStatus::QuestTroupe && cle->GetGM()) || whom->gmlookup == 0xFFFF) &&
(whom->lvllow == 0xFFFF || (cle->level() >= whom->lvllow && cle->level() <= whom->lvlhigh && (cle->Anon()==0 || admin>cle->Admin()))) &&
(whom->wclass == 0xFFFF || (cle->class_() == whom->wclass && (cle->Anon()==0 || admin>cle->Admin()))) &&
(whom->wrace == 0xFFFF || (cle->race() == whom->wrace && (cle->Anon()==0 || admin>cle->Admin()))) &&
(whomlen == 0 || (
(tmpZone != 0 && strncasecmp(tmpZone, whom->whom, whomlen) == 0) ||
strncasecmp(cle->name(),whom->whom, whomlen) == 0 ||
(strncasecmp(guild_mgr.GetGuildName(cle->GuildID()), whom->whom, whomlen) == 0) ||
(admin >= AccountStatus::GMAdmin && strncasecmp(cle->AccountName(), whom->whom, whomlen) == 0)
))
))
) {
line[0] = 0;
uint32 rankstring = 0xFFFFFFFF;
if((cle->Anon()==1 && cle->GetGM() && cle->Admin()>admin) || (idx>=20 && admin < AccountStatus::GMAdmin)){ //hide gms that are anon from lesser gms and normal players, cut off at 20
uint32 plid=fromid;
uint32 playerineqstring=5001;
const char line2[]="---------------------------";
uint8 unknown35=0x0A;
uint32 unknown36=0;
uint32 playersinzonestring=5028;
if (totalusers>20 && admin<AccountStatus::GMAdmin) {
totalusers=20;
playersinzonestring=5033;
} else if(totalusers>1) {
playersinzonestring=5036;
}
uint32 unknown44[2];
unknown44[0]=0;
unknown44[1]=0;
uint32 unknown52=totalusers;
uint32 unknown56=1;
auto pack2 = new ServerPacket(ServerOP_WhoAllReply, 64 + totallength + (49 * totalusers));
memset(pack2->pBuffer,0,pack2->size);
uchar *buffer=pack2->pBuffer;
uchar *bufptr=buffer;
//memset(buffer,0,pack2->size);
memcpy(bufptr,&plid, sizeof(uint32));
bufptr+=sizeof(uint32);
memcpy(bufptr,&playerineqstring, sizeof(uint32));
bufptr+=sizeof(uint32);
memcpy(bufptr,&line2, strlen(line2));
bufptr+=strlen(line2);
memcpy(bufptr,&unknown35, sizeof(uint8));
bufptr+=sizeof(uint8);
memcpy(bufptr,&unknown36, sizeof(uint32));
bufptr+=sizeof(uint32);
memcpy(bufptr,&playersinzonestring, sizeof(uint32));
bufptr+=sizeof(uint32);
memcpy(bufptr,&unknown44[0], sizeof(uint32));
bufptr+=sizeof(uint32);
memcpy(bufptr,&unknown44[1], sizeof(uint32));
bufptr+=sizeof(uint32);
memcpy(bufptr,&unknown52, sizeof(uint32));
bufptr+=sizeof(uint32);
memcpy(bufptr,&unknown56, sizeof(uint32));
bufptr+=sizeof(uint32);
memcpy(bufptr,&totalusers, sizeof(uint32));
bufptr+=sizeof(uint32);
iterator.Reset();
int idx=-1;
while(iterator.MoreElements()) {
cle = iterator.GetData();
const char* tmpZone = ZoneName(cle->zone());
if (
(cle->Online() >= CLE_Status::Zoning) &&
(!cle->GetGM() || cle->Anon() != 1 || admin >= cle->Admin()) &&
(whom == 0 || (
((cle->Admin() >= AccountStatus::QuestTroupe && cle->GetGM()) || whom->gmlookup == 0xFFFF) &&
(whom->lvllow == 0xFFFF || (cle->level() >= whom->lvllow && cle->level() <= whom->lvlhigh && (cle->Anon()==0 || admin>cle->Admin()))) &&
(whom->wclass == 0xFFFF || (cle->class_() == whom->wclass && (cle->Anon()==0 || admin>cle->Admin()))) &&
(whom->wrace == 0xFFFF || (cle->race() == whom->wrace && (cle->Anon()==0 || admin>cle->Admin()))) &&
(whomlen == 0 || (
(tmpZone != 0 && strncasecmp(tmpZone, whom->whom, whomlen) == 0) ||
strncasecmp(cle->name(),whom->whom, whomlen) == 0 ||
(strncasecmp(guild_mgr.GetGuildName(cle->GuildID()), whom->whom, whomlen) == 0) ||
(admin >= AccountStatus::GMAdmin && strncasecmp(cle->AccountName(), whom->whom, whomlen) == 0)
))
))
) {
line[0] = 0;
uint32 rankstring = 0xFFFFFFFF;
// These lines can be simplified but easier to conceptualize this way
if ((cle->Anon()==1 && cle->GetGM() && cle->Admin()>admin) || (idx>=20 && admin < AccountStatus::GMAdmin)) { //hide gms that are anon from lesser gms and normal players, cut off at 20
rankstring = 0;
iterator.Advance();
continue;
} else if (cle->Anon() == 1 && cle->Admin()>=admin && (whomlen == 0 || (whomlen !=0 && strncasecmp(cle->name(), whom->whom, whomlen) != 0))) {
rankstring = 0;
iterator.Advance();
continue;
} else if (cle->Anon() == 2 && cle->Admin()>=admin && (whomlen == 0 || (whomlen !=0 && strncasecmp(cle->name(), whom->whom, whomlen) != 0 && strncasecmp(guild_mgr.GetGuildName(cle->GuildID()), whom->whom, whomlen) != 0))) {
rankstring = 0;
iterator.Advance();
continue;
} else if (cle->GetGM()) {
if (cle->Admin() >= AccountStatus::GMImpossible)
if (cle->Admin() >= AccountStatus::GMImpossible) {
rankstring = 5021;
else if (cle->Admin() >= AccountStatus::GMMgmt)
} else if (cle->Admin() >= AccountStatus::GMMgmt) {
rankstring = 5020;
else if (cle->Admin() >= AccountStatus::GMCoder)
} else if (cle->Admin() >= AccountStatus::GMCoder) {
rankstring = 5019;
else if (cle->Admin() >= AccountStatus::GMAreas)
} else if (cle->Admin() >= AccountStatus::GMAreas) {
rankstring = 5018;
else if (cle->Admin() >= AccountStatus::QuestMaster)
} else if (cle->Admin() >= AccountStatus::QuestMaster) {
rankstring = 5017;
else if (cle->Admin() >= AccountStatus::GMLeadAdmin)
} else if (cle->Admin() >= AccountStatus::GMLeadAdmin) {
rankstring = 5016;
else if (cle->Admin() >= AccountStatus::GMAdmin)
} else if (cle->Admin() >= AccountStatus::GMAdmin) {
rankstring = 5015;
else if (cle->Admin() >= AccountStatus::GMStaff)
} else if (cle->Admin() >= AccountStatus::GMStaff) {
rankstring = 5014;
else if (cle->Admin() >= AccountStatus::EQSupport)
} else if (cle->Admin() >= AccountStatus::EQSupport) {
rankstring = 5013;
else if (cle->Admin() >= AccountStatus::GMTester)
} else if (cle->Admin() >= AccountStatus::GMTester) {
rankstring = 5012;
else if (cle->Admin() >= AccountStatus::SeniorGuide)
} else if (cle->Admin() >= AccountStatus::SeniorGuide) {
rankstring = 5011;
else if (cle->Admin() >= AccountStatus::QuestTroupe)
} else if (cle->Admin() >= AccountStatus::QuestTroupe) {
rankstring = 5010;
else if (cle->Admin() >= AccountStatus::Guide)
} else if (cle->Admin() >= AccountStatus::Guide) {
rankstring = 5009;
else if (cle->Admin() >= AccountStatus::ApprenticeGuide)
} else if (cle->Admin() >= AccountStatus::ApprenticeGuide) {
rankstring = 5008;
else if (cle->Admin() >= AccountStatus::Steward)
} else if (cle->Admin() >= AccountStatus::Steward) {
rankstring = 5007;
}
}
idx++;
char guildbuffer[67]={0};
if (cle->GuildID() != GUILD_NONE && cle->GuildID()>0)
sprintf(guildbuffer,"<%s>", guild_mgr.GetGuildName(cle->GuildID()));
uint32 formatstring=5025;
if(cle->Anon()==1 && (admin<cle->Admin() || admin == AccountStatus::Player))
formatstring=5024;
else if(cle->Anon()==1 && admin>=cle->Admin() && admin > AccountStatus::Player)
formatstring=5022;
else if(cle->Anon()==2 && (admin<cle->Admin() || admin == AccountStatus::Player))
formatstring=5023;//display guild
else if(cle->Anon()==2 && admin>=cle->Admin() && admin > AccountStatus::Player)
formatstring=5022;//display everything
//war* wars2 = (war*)pack2->pBuffer;
idx++;
char guildbuffer[67]={0};
uint32 plclass_=0;
uint32 pllevel=0;
uint32 pidstring=0xFFFFFFFF;//5003;
uint32 plrace=0;
uint32 zonestring=0xFFFFFFFF;
uint32 plzone=0;
uint32 unknown80[2];
if(cle->Anon()==0 || (admin>=cle->Admin() && admin> AccountStatus::Player)){
plclass_=cle->class_();
pllevel=cle->level();
if(admin>=AccountStatus::GMAdmin)
pidstring=5003;
plrace=cle->race();
zonestring=5006;
plzone=cle->zone();
}
if (cle->GuildID() != GUILD_NONE && cle->GuildID()>0) {
sprintf(guildbuffer,"<%s>", guild_mgr.GetGuildName(cle->GuildID()));
}
uint32 formatstring=5025;
if(admin>=cle->Admin() && admin > AccountStatus::Player)
unknown80[0]=cle->Admin();
else
unknown80[0]=0xFFFFFFFF;
unknown80[1]=0xFFFFFFFF;//1035
if (cle->Anon()==1 && (admin<cle->Admin() || admin == AccountStatus::Player)) {
formatstring=5024;
} else if(cle->Anon()==1 && admin>=cle->Admin() && admin > AccountStatus::Player) {
formatstring=5022;
} else if(cle->Anon()==2 && (admin<cle->Admin() || admin == AccountStatus::Player)) {
formatstring=5023;//display guild
} else if(cle->Anon()==2 && admin>=cle->Admin() && admin > AccountStatus::Player) {
formatstring=5022;//display everything
}
//war* wars2 = (war*)pack2->pBuffer;
//char plstatus[20]={0};
//sprintf(plstatus, "Status %i",cle->Admin());
char plname[64]={0};
strcpy(plname,cle->name());
uint32 plclass_=0;
uint32 pllevel=0;
uint32 pidstring=0xFFFFFFFF;//5003;
uint32 plrace=0;
uint32 zonestring=0xFFFFFFFF;
uint32 plzone=0;
uint32 unknown80[2];
char placcount[30]={0};
if(admin>=cle->Admin() && admin > AccountStatus::Player)
strcpy(placcount,cle->AccountName());
if (cle->Anon()==0 || (admin>=cle->Admin() && admin> AccountStatus::Player)) {
plclass_=cle->class_();
pllevel=cle->level();
memcpy(bufptr,&formatstring, sizeof(uint32));
bufptr+=sizeof(uint32);
memcpy(bufptr,&pidstring, sizeof(uint32));
bufptr+=sizeof(uint32);
memcpy(bufptr,&plname, strlen(plname)+1);
bufptr+=strlen(plname)+1;
memcpy(bufptr,&rankstring, sizeof(uint32));
bufptr+=sizeof(uint32);
memcpy(bufptr,&guildbuffer, strlen(guildbuffer)+1);
bufptr+=strlen(guildbuffer)+1;
memcpy(bufptr,&unknown80[0], sizeof(uint32));
bufptr+=sizeof(uint32);
memcpy(bufptr,&unknown80[1], sizeof(uint32));
bufptr+=sizeof(uint32);
memcpy(bufptr,&zonestring, sizeof(uint32));
bufptr+=sizeof(uint32);
memcpy(bufptr,&plzone, sizeof(uint32));
bufptr+=sizeof(uint32);
memcpy(bufptr,&plclass_, sizeof(uint32));
bufptr+=sizeof(uint32);
memcpy(bufptr,&pllevel, sizeof(uint32));
bufptr+=sizeof(uint32);
memcpy(bufptr,&plrace, sizeof(uint32));
bufptr+=sizeof(uint32);
uint32 ending=0;
memcpy(bufptr,&placcount, strlen(placcount)+1);
bufptr+=strlen(placcount)+1;
ending=207;
memcpy(bufptr,&ending, sizeof(uint32));
bufptr+=sizeof(uint32);
if(admin>=AccountStatus::GMAdmin) {
pidstring=5003;
}
plrace=cle->race();
zonestring=5006;
plzone=cle->zone();
}
if (admin>=cle->Admin() && admin > AccountStatus::Player) {
unknown80[0]=cle->Admin();
} else {
unknown80[0]=0xFFFFFFFF;
}
unknown80[1]=0xFFFFFFFF;//1035
//char plstatus[20]={0};
//sprintf(plstatus, "Status %i",cle->Admin());
char plname[64]={0};
strcpy(plname,cle->name());
char placcount[30]={0};
if (admin>=cle->Admin() && admin > AccountStatus::Player) {
strcpy(placcount,cle->AccountName());
}
memcpy(bufptr,&formatstring, sizeof(uint32));
bufptr+=sizeof(uint32);
memcpy(bufptr,&pidstring, sizeof(uint32));
bufptr+=sizeof(uint32);
memcpy(bufptr,&plname, strlen(plname)+1);
bufptr+=strlen(plname)+1;
memcpy(bufptr,&rankstring, sizeof(uint32));
bufptr+=sizeof(uint32);
memcpy(bufptr,&guildbuffer, strlen(guildbuffer)+1);
bufptr+=strlen(guildbuffer)+1;
memcpy(bufptr,&unknown80[0], sizeof(uint32));
bufptr+=sizeof(uint32);
memcpy(bufptr,&unknown80[1], sizeof(uint32));
bufptr+=sizeof(uint32);
memcpy(bufptr,&zonestring, sizeof(uint32));
bufptr+=sizeof(uint32);
memcpy(bufptr,&plzone, sizeof(uint32));
bufptr+=sizeof(uint32);
memcpy(bufptr,&plclass_, sizeof(uint32));
bufptr+=sizeof(uint32);
memcpy(bufptr,&pllevel, sizeof(uint32));
bufptr+=sizeof(uint32);
memcpy(bufptr,&plrace, sizeof(uint32));
bufptr+=sizeof(uint32);
uint32 ending=0;
memcpy(bufptr,&placcount, strlen(placcount)+1);
bufptr+=strlen(placcount)+1;
ending=207;
memcpy(bufptr,&ending, sizeof(uint32));
bufptr+=sizeof(uint32);
}
iterator.Advance();
}
iterator.Advance();
}
//zoneserver_list.SendPacket(pack2); // NO NO NO WHY WOULD YOU SEND IT TO EVERY ZONE SERVER?!?
SendPacket(to,pack2);
safe_delete(pack2);
}
catch(...){
SendPacket(to,pack2);
safe_delete(pack2);
} catch(...) {
LogInfo("Unknown error in world's SendWhoAll (probably mem error), ignoring");
return;
}
+5 -5
View File
@@ -222,7 +222,7 @@ void NPC::DescribeAggro(Client *to_who, Mob *mob, bool verbose) {
if (
GetLevel() < RuleI(Aggro, MinAggroLevel) &&
mob->GetLevelCon(GetLevel()) == ConsiderColor::Gray &&
GetBodyType() != BT_Undead &&
GetBodyType() != BodyType::Undead &&
!AlwaysAggro()
) {
to_who->Message(
@@ -496,7 +496,7 @@ bool Mob::CheckWillAggro(Mob *mob) {
RuleB(Aggro, UseLevelAggro) &&
(
GetLevel() >= RuleI(Aggro, MinAggroLevel) ||
GetBodyType() == BT_Undead ||
GetBodyType() == BodyType::Undead ||
AlwaysAggro() ||
(
mob->IsClient() &&
@@ -524,7 +524,7 @@ bool Mob::CheckWillAggro(Mob *mob) {
} else {
if (
(
(RuleB(Aggro, UndeadAlwaysAggro) && GetBodyType() == BT_Undead) ||
(RuleB(Aggro, UndeadAlwaysAggro) && GetBodyType() == BodyType::Undead) ||
(GetINT() <= RuleI(Aggro, IntAggroThreshold)) ||
AlwaysAggro() ||
(
@@ -671,9 +671,9 @@ bool Mob::IsAttackAllowed(Mob *target, bool isSpellAttack)
target_owner = nullptr;
//cannot hurt untargetable mobs
bodyType bt = target->GetBodyType();
uint8 bt = target->GetBodyType();
if(bt == BT_NoTarget || bt == BT_NoTarget2) {
if(bt == BodyType::NoTarget || bt == BodyType::NoTarget2) {
if (RuleB(Pets, UnTargetableSwarmPet)) {
if (target->IsNPC()) {
if (!target->CastToNPC()->GetSwarmOwner()) {
+3 -3
View File
@@ -4593,10 +4593,10 @@ void Mob::CommonDamage(Mob* attacker, int64 &damage, const uint16 spell_id, cons
//this was done to simplify the code here (since we can only effectively skip one mob on queue)
eqFilterType filter;
Mob* skip = attacker;
if (attacker && attacker->IsPet() && !attacker->IsBot()) {
Mob* owner = attacker ? attacker->GetOwner() : nullptr;
if (attacker && owner && !attacker->IsBot()) {
//attacker is a pet, let pet owners see their pet's damage
Mob* owner = attacker->GetOwner();
if (owner && owner->IsClient()) {
if (owner->IsClient()) {
if (FromDamageShield && damage > 0) {
//special crap for spell damage, looks hackish to me
char val1[20] = { 0 };
+1 -1
View File
@@ -52,7 +52,7 @@ Beacon::Beacon(const glm::vec4 &in_pos, int lifetime) : Mob(
Gender::Male, // in_gender
Race::InvisibleMan, // in_race
Class::None, // in_class
BT_NoTarget, // in_bodytype
BodyType::NoTarget, // in_bodytype
Deity::Unknown, // in_deity
0, // in_level
0, // in_npctype_id
+4
View File
@@ -2438,6 +2438,10 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
case SE_CastingLevel2:
{
new_bonus->effective_casting_level += effect_value;
if (RuleB(Spells, SnareOverridesSpeedBonuses) && effect_value < 0) {
new_bonus->movementspeed = effect_value;
}
break;
}
+2 -2
View File
@@ -5481,13 +5481,13 @@ bool Bot::IsImmuneToSpell(uint16 spell_id, Mob *caster) {
if (!Result) {
if (caster->IsBot()) {
if (spells[spell_id].target_type == ST_Undead) {
if ((GetBodyType() != BT_SummonedUndead) && (GetBodyType() != BT_Undead) && (GetBodyType() != BT_Vampire)) {
if ((GetBodyType() != BodyType::SummonedUndead) && (GetBodyType() != BodyType::Undead) && (GetBodyType() != BodyType::Vampire)) {
LogSpellsDetail("Bot's target is not an undead");
return true;
}
}
if (spells[spell_id].target_type == ST_Summoned) {
if ((GetBodyType() != BT_SummonedUndead) && (GetBodyType() != BT_Summoned) && (GetBodyType() != BT_Summoned2) && (GetBodyType() != BT_Summoned3)) {
if ((GetBodyType() != BodyType::SummonedUndead) && (GetBodyType() != BodyType::Summoned) && (GetBodyType() != BodyType::Summoned2) && (GetBodyType() != BodyType::Summoned3)) {
LogSpellsDetail("Bot's target is not a summoned creature");
return true;
}
+8 -8
View File
@@ -753,19 +753,19 @@ namespace ActionableTarget
verified_friendly = target_mob;
break;
case BCEnum::TT_Animal:
if (target_mob && target_mob->GetBodyType() == BT_Animal)
if (target_mob && target_mob->GetBodyType() == BodyType::Animal)
verified_friendly = target_mob;
break;
case BCEnum::TT_Undead:
if (target_mob && target_mob->GetBodyType() == BT_Undead)
if (target_mob && target_mob->GetBodyType() == BodyType::Undead)
verified_friendly = target_mob;
break;
case BCEnum::TT_Summoned:
if (target_mob && target_mob->GetBodyType() == BT_Summoned)
if (target_mob && target_mob->GetBodyType() == BodyType::Summoned)
verified_friendly = target_mob;
break;
case BCEnum::TT_Plant:
if (target_mob && target_mob->GetBodyType() == BT_Plant)
if (target_mob && target_mob->GetBodyType() == BodyType::Plant)
verified_friendly = target_mob;
break;
case BCEnum::TT_Corpse:
@@ -800,19 +800,19 @@ namespace ActionableTarget
Mob* verified_enemy = nullptr;
switch (target_type) {
case BCEnum::TT_Animal:
if (target_mob->GetBodyType() == BT_Animal)
if (target_mob->GetBodyType() == BodyType::Animal)
verified_enemy = target_mob;
break;
case BCEnum::TT_Undead:
if (target_mob->GetBodyType() == BT_Undead)
if (target_mob->GetBodyType() == BodyType::Undead)
verified_enemy = target_mob;
break;
case BCEnum::TT_Summoned:
if (target_mob->GetBodyType() == BT_Summoned)
if (target_mob->GetBodyType() == BodyType::Summoned)
verified_enemy = target_mob;
break;
case BCEnum::TT_Plant:
if (target_mob->GetBodyType() == BT_Plant)
if (target_mob->GetBodyType() == BodyType::Plant)
verified_enemy = target_mob;
break;
case BCEnum::TT_Single:
+2 -2
View File
@@ -771,9 +771,9 @@ bool Bot::BotCastNuke(Mob* tar, uint8 botLevel, uint8 botClass, BotSpell& botSpe
}
if (botClass == Class::Magician || botClass == Class::ShadowKnight || botClass == Class::Necromancer || botClass == Class::Paladin || botClass == Class::Ranger || botClass == Class::Druid || botClass == Class::Cleric) {
if (tar->GetBodyType() == BT_Undead || tar->GetBodyType() == BT_SummonedUndead || tar->GetBodyType() == BT_Vampire)
if (tar->GetBodyType() == BodyType::Undead || tar->GetBodyType() == BodyType::SummonedUndead || tar->GetBodyType() == BodyType::Vampire)
botSpell = GetBestBotSpellForNukeByTargetType(this, ST_Undead);
else if (tar->GetBodyType() == BT_Summoned || tar->GetBodyType() == BT_Summoned2 || tar->GetBodyType() == BT_Summoned3)
else if (tar->GetBodyType() == BodyType::Summoned || tar->GetBodyType() == BodyType::Summoned2 || tar->GetBodyType() == BodyType::Summoned3)
botSpell = GetBestBotSpellForNukeByTargetType(this, ST_Summoned);
}
+1 -1
View File
@@ -95,7 +95,7 @@ Client::Client(EQStreamInterface *ieqs) : Mob(
Gender::Male, // in_gender
Race::Doug, // in_race
Class::None, // in_class
BT_Humanoid, // in_bodytype
BodyType::Humanoid, // in_bodytype
Deity::Unknown, // in_deity
0, // in_level
0, // in_npctype_id
+16 -10
View File
@@ -10434,7 +10434,7 @@ void Client::Handle_OP_Mend(const EQApplicationPacket *app)
int mendhp = GetMaxHP() / 4;
int currenthp = GetHP();
if (zone->random.Int(0, 199) < (int)GetSkill(EQ::skills::SkillMend)) {
if (zone->random.Int(0, RuleI(Character, MendAlwaysSucceedValue)) < (int)GetSkill(EQ::skills::SkillMend)) {
int criticalchance = spellbonuses.CriticalMend + itembonuses.CriticalMend + aabonuses.CriticalMend;
@@ -11882,8 +11882,8 @@ void Client::Handle_OP_PickPocket(const EQApplicationPacket *app)
}
else if (victim->IsNPC()) {
auto body = victim->GetBodyType();
if (body == BT_Humanoid || body == BT_Monster || body == BT_Giant ||
body == BT_Lycanthrope) {
if (body == BodyType::Humanoid || body == BodyType::Monster || body == BodyType::Giant ||
body == BodyType::Lycanthrope) {
victim->CastToNPC()->PickPocket(this);
return;
}
@@ -14644,12 +14644,18 @@ void Client::Handle_OP_Sneak(const EQApplicationPacket *app)
sa_out->parameter = 0;
entity_list.QueueClients(this, outapp, true);
safe_delete(outapp);
}
else {
} else {
CheckIncreaseSkill(EQ::skills::SkillSneak, nullptr, 5);
}
float hidechance = ((GetSkill(EQ::skills::SkillSneak) / 300.0f) + .25) * 100;
if (RuleB(Character, SneakAlwaysSucceedOver100)) {
hidechance = std::max(10, (int)GetSkill(EQ::skills::SkillSneak));
}
float random = zone->random.Real(0, 99);
if (!was && random < hidechance) {
sneaking = true;
}
@@ -14999,9 +15005,9 @@ void Client::Handle_OP_TargetCommand(const EQApplicationPacket *app)
if (nt) {
if (GetGM() || (!nt->IsInvisible(this) && (DistanceSquared(m_Position, nt->GetPosition()) <= TARGETING_RANGE*TARGETING_RANGE))) {
if (nt->GetBodyType() == BT_NoTarget2 ||
nt->GetBodyType() == BT_Special ||
nt->GetBodyType() == BT_NoTarget) {
if (nt->GetBodyType() == BodyType::NoTarget2 ||
nt->GetBodyType() == BodyType::Special ||
nt->GetBodyType() == BodyType::NoTarget) {
can_target = false;
}
else {
@@ -15144,8 +15150,8 @@ void Client::Handle_OP_TargetMouse(const EQApplicationPacket *app)
GetTarget()->IsTargeted(1);
return;
}
else if (GetTarget()->GetBodyType() == BT_NoTarget2 || GetTarget()->GetBodyType() == BT_Special
|| GetTarget()->GetBodyType() == BT_NoTarget)
else if (GetTarget()->GetBodyType() == BodyType::NoTarget2 || GetTarget()->GetBodyType() == BodyType::Special
|| GetTarget()->GetBodyType() == BodyType::NoTarget)
{
auto message = fmt::format(
"[{}] attempting to target something untargetable [{}] bodytype [{}]",
+3 -3
View File
@@ -70,7 +70,7 @@ Corpse::Corpse(
npc->GetGender(), // in_gender
npc->GetRace(), // in_race
npc->GetClass(), // in_class
BT_Humanoid, // in_bodytype
BodyType::Humanoid, // in_bodytype
npc->GetDeity(), // in_deity
npc->GetLevel(), // in_level
npc->GetNPCTypeID(), // in_npctype_id
@@ -189,7 +189,7 @@ Corpse::Corpse(Client *c, int32 rez_exp, KilledByTypes in_killed_by) : Mob(
c->GetGender(), // in_gender
c->GetRace(), // in_race
c->GetClass(), // in_class
BT_Humanoid, // in_bodytype
BodyType::Humanoid, // in_bodytype
c->GetDeity(), // in_deity
c->GetLevel(), // in_level
0, // in_npctype_id
@@ -495,7 +495,7 @@ Corpse::Corpse(
gender, // in_gender
race, // in_race
class_, // in_class
BT_Humanoid, // in_bodytype
BodyType::Humanoid, // in_bodytype
deity, // in_deity
level, // in_level
0, // in_npctype_id
+31 -32
View File
@@ -71,20 +71,20 @@ int64 Mob::GetActSpellDamage(uint16 spell_id, int64 value, Mob* target) {
int32 ratio = RuleI(Spells, BaseCritRatio); //Critical modifier is applied from spell effects only. Keep at 100 for live like criticals.
//Improved Harm Touch is a guaranteed crit if you have at least one level of SCF.
if (spell_id == SPELL_IMP_HARM_TOUCH && IsOfClientBot() && (GetAA(aaSpellCastingFury) > 0) && (GetAA(aaUnholyTouch) > 0))
if (spell_id == SPELL_IMP_HARM_TOUCH && IsOfClientBot() && (GetAA(aaSpellCastingFury) > 0) && (GetAA(aaUnholyTouch) > 0)) {
chance = 100;
}
if (spells[spell_id].override_crit_chance > 0 && chance > spells[spell_id].override_crit_chance)
if (spells[spell_id].override_crit_chance > 0 && chance > spells[spell_id].override_crit_chance) {
chance = spells[spell_id].override_crit_chance;
}
if (zone->random.Roll(chance)) {
Critical = true;
ratio += itembonuses.SpellCritDmgIncrease + spellbonuses.SpellCritDmgIncrease + aabonuses.SpellCritDmgIncrease;
ratio += itembonuses.SpellCritDmgIncNoStack + spellbonuses.SpellCritDmgIncNoStack + aabonuses.SpellCritDmgIncNoStack;
}
else if ((IsOfClientBot() && GetClass() == Class::Wizard) || (IsMerc() && GetClass() == CASTERDPS)) {
if ((GetLevel() >= RuleI(Spells, WizCritLevel)) && zone->random.Roll(RuleI(Spells, WizCritChance))){
} else if ((IsOfClientBot() && GetClass() == Class::Wizard) || (IsMerc() && GetClass() == CASTERDPS)) {
if ((GetLevel() >= RuleI(Spells, WizCritLevel)) && zone->random.Roll(RuleI(Spells, WizCritChance))) {
//Wizard innate critical chance is calculated seperately from spell effect and is not a set ratio. (20-70 is parse confirmed)
ratio += zone->random.Int(RuleI(Spells, WizardCritMinimumRandomRatio), RuleI(Spells, WizardCritMaximumRandomRatio));
Critical = true;
@@ -100,21 +100,32 @@ int64 Mob::GetActSpellDamage(uint16 spell_id, int64 value, Mob* target) {
}
if (Critical) {
value = base_value*ratio/100;
value += base_value*GetFocusEffect(focusImprovedDamage, spell_id)/100;
value += base_value*GetFocusEffect(focusImprovedDamage2, spell_id)/100;
if (RuleB(Spells, UseClassicHarmTouchDamage)) {
// Need to scale HT damage differently after level 40! It no longer scales by the constant value in the spell file. It scales differently, instead of 10 more damage per level, it does 30 more damage per level. So we multiply the level minus 40 times 20 if they are over level 40.
if (IsHarmTouchSpell(spell_id) && GetLevel() > 40) {
value -= (GetLevel() - 40) * 20;
}
value += int(base_value*GetFocusEffect(focusFcDamagePctCrit, spell_id)/100)*ratio/100;
value += int(base_value*GetFocusEffect(focusFcAmplifyMod, spell_id) / 100)*ratio / 100;
//This adds the extra damage from the AA Unholy Touch, 450 per level to the AA Improved Harm TOuch.
if (spell_id == SPELL_IMP_HARM_TOUCH && IsOfClientBotMerc()) { //Improved Harm Touch
value -= GetAA(aaUnholyTouch) * 450; //Unholy Touch
}
}
value += base_value*GetFocusEffect(focusImprovedDamage, spell_id) / 100;
value += base_value*GetFocusEffect(focusImprovedDamage2, spell_id) / 100;
value += int(base_value*GetFocusEffect(focusFcDamagePctCrit, spell_id) / 100) * ratio / 100;
value += int(base_value*GetFocusEffect(focusFcAmplifyMod, spell_id) / 100) * ratio / 100;
if (target) {
value += int(base_value*target->GetVulnerability(this, spell_id, 0)/100)*ratio/100;
value += int(base_value*target->GetVulnerability(this, spell_id, 0) / 100) * ratio / 100;
value -= target->GetFcDamageAmtIncoming(this, spell_id);
}
value -= GetFocusEffect(focusFcDamageAmtCrit, spell_id)*ratio/100;
value -= GetFocusEffect(focusFcDamageAmtCrit, spell_id) * ratio / 100;
value -= GetFocusEffect(focusFcDamageAmt, spell_id);
value -= GetFocusEffect(focusFcDamageAmt2, spell_id);
@@ -127,9 +138,7 @@ int64 Mob::GetActSpellDamage(uint16 spell_id, int64 value, Mob* target) {
if (RuleB(Spells, IgnoreSpellDmgLvlRestriction) && !spells[spell_id].no_heal_damage_item_mod && itembonuses.SpellDmg) {
value -= GetExtraSpellAmt(spell_id, itembonuses.SpellDmg, base_value) * ratio / 100;
}
else if (!spells[spell_id].no_heal_damage_item_mod && itembonuses.SpellDmg && spells[spell_id].classes[(GetClass() % 17) - 1] >= GetLevel() - 5) {
} else if (!spells[spell_id].no_heal_damage_item_mod && itembonuses.SpellDmg && spells[spell_id].classes[(GetClass() % 17) - 1] >= GetLevel() - 5) {
value -= GetExtraSpellAmt(spell_id, itembonuses.SpellDmg, base_value) * ratio / 100;
}
@@ -148,30 +157,20 @@ int64 Mob::GetActSpellDamage(uint16 spell_id, int64 value, Mob* target) {
MessageString(Chat::SpellCrit, YOU_CRIT_BLAST, itoa(-value));
}
// Need to scale HT damage differently after level 40! It no longer scales by the constant value in the spell file. It scales differently, instead of 10 more damage per level, it does 30 more damage per level. So we multiply the level minus 40 times 20 if they are over level 40.
if (IsHarmTouchSpell(spell_id) && GetLevel() > 40) {
value -= (GetLevel() - 40) * 20;
}
//This adds the extra damage from the AA Unholy Touch, 450 per level to the AA Improved Harm Touch.
if (spell_id == SPELL_IMP_HARM_TOUCH && IsOfClientBot()) { //Improved Harm Touch
value -= GetAA(aaUnholyTouch) * 450; //Unholy Touch
}
return value;
}
}
//Non Crtical Hit Calculation pathway
value = base_value;
value += base_value*GetFocusEffect(focusImprovedDamage, spell_id)/100;
value += base_value*GetFocusEffect(focusImprovedDamage2, spell_id)/100;
value += base_value*GetFocusEffect(focusImprovedDamage, spell_id) / 100;
value += base_value*GetFocusEffect(focusImprovedDamage2, spell_id) / 100;
value += base_value*GetFocusEffect(focusFcDamagePctCrit, spell_id)/100;
value += base_value*GetFocusEffect(focusFcAmplifyMod, spell_id)/100;
value += base_value*GetFocusEffect(focusFcDamagePctCrit, spell_id) / 100;
value += base_value*GetFocusEffect(focusFcAmplifyMod, spell_id) / 100;
if (target) {
value += base_value*target->GetVulnerability(this, spell_id, 0)/100;
value += base_value*target->GetVulnerability(this, spell_id, 0) / 100;
value -= target->GetFcDamageAmtIncoming(this, spell_id);
}
@@ -614,7 +613,7 @@ int32 Mob::GetActSpellDuration(uint16 spell_id, int32 duration)
{
// focuses don't affect discipline duration (Except War Cries)
if (
IsDiscipline(spell_id) &&
IsDiscipline(spell_id) &&
(
spell_id != SPELL_BATTLE_CRY &&
spell_id != SPELL_WAR_CRY &&
+2 -2
View File
@@ -4740,9 +4740,9 @@ std::string Perl__getlanguagename(uint8 language_id)
return quest_manager.getlanguagename(language_id);
}
std::string Perl__getbodytypename(uint32 bodytype_id)
std::string Perl__getbodytypename(uint8 body_type_id)
{
return quest_manager.getbodytypename(bodytype_id);
return quest_manager.getbodytypename(body_type_id);
}
std::string Perl__getconsiderlevelname(uint8 consider_level)
+1 -1
View File
@@ -40,7 +40,7 @@ Encounter::Encounter(const char *enc_name) : Mob(
Gender::Male, // in_gender
Race::InvisibleMan, // in_race
Class::None, // in_class
BT_NoTarget, // in_bodytype
BodyType::NoTarget, // in_bodytype
Deity::Unknown, // in_deity
0, // in_level
0, // in_npcype_id
+8 -8
View File
@@ -5059,7 +5059,7 @@ uint32 EntityList::CheckNPCsClose(Mob *center)
while (it != npc_list.end()) {
NPC *cur = it->second;
if (!cur || cur == center || cur->IsPet() || cur->GetClass() == Class::LDoNTreasure ||
cur->GetBodyType() == BT_NoTarget || cur->GetBodyType() == BT_Special) {
cur->GetBodyType() == BodyType::NoTarget || cur->GetBodyType() == BodyType::Special) {
++it;
continue;
}
@@ -5419,9 +5419,9 @@ void EntityList::AddLootToNPCS(uint32 item_id, uint32 count)
while (it != npc_list.end()) {
if (!it->second->IsPet()
&& it->second->GetClass() != Class::LDoNTreasure
&& it->second->GetBodyType() != BT_NoTarget
&& it->second->GetBodyType() != BT_NoTarget2
&& it->second->GetBodyType() != BT_Special)
&& it->second->GetBodyType() != BodyType::NoTarget
&& it->second->GetBodyType() != BodyType::NoTarget2
&& it->second->GetBodyType() != BodyType::Special)
npc_count++;
++it;
}
@@ -5440,9 +5440,9 @@ void EntityList::AddLootToNPCS(uint32 item_id, uint32 count)
while (it != npc_list.end()) {
if (!it->second->IsPet()
&& it->second->GetClass() != Class::LDoNTreasure
&& it->second->GetBodyType() != BT_NoTarget
&& it->second->GetBodyType() != BT_NoTarget2
&& it->second->GetBodyType() != BT_Special)
&& it->second->GetBodyType() != BodyType::NoTarget
&& it->second->GetBodyType() != BodyType::NoTarget2
&& it->second->GetBodyType() != BodyType::Special)
npcs[i++] = it->second;
++it;
}
@@ -5520,7 +5520,7 @@ void EntityList::ExpeditionWarning(uint32 minutes_left)
safe_delete(outapp);
}
Mob *EntityList::GetClosestMobByBodyType(Mob *sender, bodyType BodyType, bool skip_client_pets)
Mob *EntityList::GetClosestMobByBodyType(Mob *sender, uint8 BodyType, bool skip_client_pets)
{
if (!sender)
+1 -1
View File
@@ -505,7 +505,7 @@ public:
void TryWakeTheDead(Mob* sender, Mob* target, int32 spell_id, uint32 max_distance, uint32 duration, uint32 amount_pets);
NPC* GetClosestBanker(Mob* sender, uint32 &distance);
void CameraEffect(uint32 duration, float intensity);
Mob* GetClosestMobByBodyType(Mob* sender, bodyType BodyType, bool skip_client_pets=false);
Mob* GetClosestMobByBodyType(Mob* sender, uint8 BodyType, bool skip_client_pets=false);
void ForceGroupUpdate(uint32 gid);
void SendGroupLeave(uint32 gid, const char *name);
void SendGroupJoin(uint32 gid, const char *name);
+1 -1
View File
@@ -50,7 +50,7 @@ void Mob::CheckFlee()
}
// Undead do not flee
if (GetBodyType() == BT_Undead) {
if (GetBodyType() == BodyType::Undead) {
return;
}
+4
View File
@@ -1,5 +1,6 @@
#include "../client.h"
#include "find/aa.cpp"
#include "find/body_type.cpp"
#include "find/bug_category.cpp"
#include "find/character.cpp"
#include "find/class.cpp"
@@ -11,6 +12,7 @@
#include "find/item.cpp"
#include "find/language.cpp"
#include "find/npctype.cpp"
#include "find/object_type.cpp"
#include "find/race.cpp"
#include "find/recipe.cpp"
#include "find/skill.cpp"
@@ -33,6 +35,7 @@ void command_find(Client *c, const Seperator *sep)
std::vector<Cmd> commands = {
Cmd{.cmd = "aa", .u = "aa [Search Criteria]", .fn = FindAA, .a = {"#findaa"}},
Cmd{.cmd = "body_type", .u = "body_type [Search Criteria]", .fn = FindBodyType, .a = {"#findbodytype"}},
Cmd{.cmd = "bug_category", .u = "bug_category [Search Criteria]", .fn = FindBugCategory, .a = {"#findbugcategory"}},
Cmd{.cmd = "character", .u = "character [Search Criteria]", .fn = FindCharacter, .a = {"#findcharacter"}},
Cmd{.cmd = "class", .u = "class [Search Criteria]", .fn = FindClass, .a = {"#findclass"}},
@@ -50,6 +53,7 @@ void command_find(Client *c, const Seperator *sep)
"#findnpctype"
}
},
Cmd{.cmd = "object_type", .u = "object_type [Search Criteria]", .fn = FindObjectType, .a = {"#findobjecttype"}},
Cmd{.cmd = "race", .u = "race [Search Criteria]", .fn = FindRace, .a = {"#findrace"}},
Cmd{.cmd = "recipe", .u = "recipe [Search Criteria]", .fn = FindRecipe, .a = {"#findrecipe"}},
Cmd{.cmd = "skill", .u = "skill [Search Criteria]", .fn = FindSkill, .a = {"#findskill"}},
+62
View File
@@ -0,0 +1,62 @@
#include "../../client.h"
void FindBodyType(Client *c, const Seperator *sep)
{
if (sep->IsNumber(2)) {
const uint8 body_type_id = static_cast<uint8>(Strings::ToUnsignedInt(sep->arg[2]));
const std::string& body_type_name = BodyType::GetName(body_type_id);
if (Strings::EqualFold(body_type_name, "UNKNOWN BODY TYPE")) {
c->Message(
Chat::White,
fmt::format(
"Body Type {} does not exist.",
body_type_id
).c_str()
);
return;
}
c->Message(
Chat::White,
fmt::format(
"Body Type {} | {}",
body_type_id,
body_type_name
).c_str()
);
return;
}
const std::string& search_criteria = Strings::ToLower(sep->argplus[2]);
uint32 found_count = 0;
for (const auto& e : body_type_names) {
const std::string& body_type_name_lower = Strings::ToLower(e.second);
if (!Strings::Contains(body_type_name_lower, search_criteria)) {
continue;
}
c->Message(
Chat::White,
fmt::format(
"Body Type {} | {}",
e.first,
e.second
).c_str()
);
found_count++;
}
c->Message(
Chat::White,
fmt::format(
"{} Body Type{} found matching '{}'.",
found_count,
found_count != 1 ? "s" : "",
sep->argplus[2]
).c_str()
);
}
+65
View File
@@ -0,0 +1,65 @@
#include "../../client.h"
void FindObjectType(Client *c, const Seperator *sep)
{
if (sep->IsNumber(2)) {
const uint32 object_type = Strings::ToUnsignedInt(sep->arg[2]);
const std::string& object_type_name = ObjectType::GetName(object_type);
if (Strings::EqualFold(object_type_name, "UNKNOWN OBJECT TYPE")) {
c->Message(
Chat::White,
fmt::format(
"Object Type {} does not exist.",
object_type
).c_str()
);
return;
}
c->Message(
Chat::White,
fmt::format(
"Object Type {} | {}",
object_type,
ObjectType::GetName(object_type)
).c_str()
);
return;
}
const std::string& search_criteria = Strings::ToLower(sep->argplus[2]);
uint32 found_count = 0;
for (const auto& e : object_types) {
const std::string& object_type_name_lower = Strings::ToLower(e.second);
if (!Strings::Contains(object_type_name_lower, search_criteria)) {
continue;
}
c->Message(
Chat::White,
fmt::format(
"Object Type {} | {}",
e.first,
e.second
).c_str()
);
found_count++;
}
c->Message(
Chat::White,
fmt::format(
"{} Object Type{} found matching '{}'.",
found_count,
found_count != 1 ? "s" : "",
sep->argplus[2]
).c_str()
);
}
+9 -1
View File
@@ -4,7 +4,7 @@ void command_goto(Client *c, const Seperator *sep)
{
const uint16 arguments = sep->argnum;
const bool goto_player = !sep->IsNumber(1) && sep->arg[1];
const bool goto_player = arguments > 0 && !sep->IsNumber(1);
const bool goto_position = sep->IsNumber(1) && sep->IsNumber(2) && sep->IsNumber(3);
const bool goto_target = !arguments && c->GetTarget();
@@ -78,6 +78,14 @@ void command_goto(Client *c, const Seperator *sep)
t->GetZ(),
t->GetHeading()
);
c->Message(
Chat::White,
fmt::format(
"Going to {} in the same zone.",
c->GetTargetDescription(t)
).c_str()
);
}
}
+16 -12
View File
@@ -100,21 +100,25 @@ void command_npcedit(Client *c, const Seperator *sep)
}
} else if (!strcasecmp(sep->arg[1], "bodytype")) {
if (sep->IsNumber(2)) {
auto body_type_id = static_cast<uint8_t>(Strings::ToUnsignedInt(sep->arg[2]));
auto body_type_name = EQ::constants::GetBodyTypeName(static_cast<bodyType>(body_type_id));
const uint8 body_type_id = static_cast<uint8>(Strings::ToUnsignedInt(sep->arg[2]));
const std::string& body_type_name = BodyType::GetName(body_type_id);
if (Strings::EqualFold(body_type_name, "UNKNOWN BODY TYPE")) {
c->Message(
Chat::White,
fmt::format(
"Body Type {} does not exist.",
body_type_id
).c_str()
);
return;
}
n.bodytype = body_type_id;
d = fmt::format(
"{} is now using Body Type {}.",
"{} is now using Body Type {} ({}).",
npc_id_string,
(
!body_type_name.empty() ?
fmt::format(
"{} ({})",
body_type_name,
body_type_id
) :
std::to_string(body_type_id)
)
body_type_name,
body_type_id
);
} else {
c->Message(Chat::White, "Usage: #npcedit bodytype [Body Type ID] - Sets an NPC's Bodytype");
+2 -2
View File
@@ -54,8 +54,8 @@ void ShowRecipe(Client *c, const Seperator *sep)
e.iscontainer > 0 ? " (Container)" : "",
(
e.item_id > 1000 ?
database.CreateItemLink(e.item_id) :
EQ::constants::GetObjectTypeName(e.item_id)
database.CreateItemLink(static_cast<uint32>(e.item_id)) :
ObjectType::GetName(static_cast<uint32>(e.item_id))
),
(
can_summon_items && e.item_id > 1000 ?
+1 -1
View File
@@ -174,7 +174,7 @@ void ShowWho(Client *c, const Seperator *sep)
account_status ?
fmt::format(
"* {} * ",
EQ::constants::GetAccountStatusName(account_status)
AccountStatus::GetName(account_status)
) :
""
);
+2 -2
View File
@@ -384,7 +384,7 @@ bool Client::SummonItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2,
return false;
}
if(item->AugSlotVisible[iter] == 0) {
if (!RuleB(Items, SummonItemAllowInvisibleAugments) && item->AugSlotVisible[iter] == 0) {
Message(
Chat::Red,
fmt::format(
@@ -1105,7 +1105,7 @@ void Client::DeleteItemInInventory(int16 slot_id, int16 quantity, bool client_up
if(update_db)
database.SaveInventory(character_id, inst, slot_id);
}
if(client_update && IsValidSlot(slot_id)) {
EQApplicationPacket* outapp = nullptr;
if(inst) {
+2 -2
View File
@@ -3790,8 +3790,8 @@ std::string lua_get_language_name(uint8 language_id) {
return quest_manager.getlanguagename(language_id);
}
std::string lua_get_body_type_name(uint32 bodytype_id) {
return quest_manager.getbodytypename(bodytype_id);
std::string lua_get_body_type_name(uint8 body_type_id) {
return quest_manager.getbodytypename(body_type_id);
}
std::string lua_get_consider_level_name(uint8 consider_level) {
+3 -3
View File
@@ -1995,9 +1995,9 @@ void Lua_Mob::SetRunning(bool running) {
self->SetRunning(running);
}
void Lua_Mob::SetBodyType(int new_body, bool overwrite_orig) {
void Lua_Mob::SetBodyType(uint8 new_body, bool overwrite_orig) {
Lua_Safe_Call_Void();
self->SetBodyType(static_cast<bodyType>(new_body), overwrite_orig);
self->SetBodyType(new_body, overwrite_orig);
}
void Lua_Mob::SetTargetable(bool on) {
@@ -3869,7 +3869,7 @@ luabind::scope lua_register_mob() {
.def("SetAllowBeneficial", (void(Lua_Mob::*)(bool))&Lua_Mob::SetAllowBeneficial)
.def("SetAppearance", (void(Lua_Mob::*)(int))&Lua_Mob::SetAppearance)
.def("SetAppearance", (void(Lua_Mob::*)(int,bool))&Lua_Mob::SetAppearance)
.def("SetBodyType", (void(Lua_Mob::*)(int,bool))&Lua_Mob::SetBodyType)
.def("SetBodyType", (void(Lua_Mob::*)(uint8,bool))&Lua_Mob::SetBodyType)
.def("SetBucket", (void(Lua_Mob::*)(std::string,std::string))&Lua_Mob::SetBucket)
.def("SetBucket", (void(Lua_Mob::*)(std::string,std::string,std::string))&Lua_Mob::SetBucket)
.def("SetBuffDuration", (void(Lua_Mob::*)(int))&Lua_Mob::SetBuffDuration)
+1 -1
View File
@@ -399,7 +399,7 @@ public:
void RemoveAllNimbusEffects();
bool IsRunning();
void SetRunning(bool running);
void SetBodyType(int new_body, bool overwrite_orig);
void SetBodyType(uint8 new_body, bool overwrite_orig);
void SetTargetable(bool on);
void ModSkillDmgTaken(int skill, int value);
int GetModSkillDmgTaken(int skill);
+5 -5
View File
@@ -52,7 +52,7 @@ Mob::Mob(
uint8 in_gender,
uint16 in_race,
uint8 in_class,
bodyType in_bodytype,
uint8 in_bodytype,
uint8 in_deity,
uint8 in_level,
uint32 in_npctype_id,
@@ -696,14 +696,14 @@ bool Mob::IsInvisible(Mob* other) const
}
//check invis vs. undead
if (other->GetBodyType() == BT_Undead || other->GetBodyType() == BT_SummonedUndead) {
if (other->GetBodyType() == BodyType::Undead || other->GetBodyType() == BodyType::SummonedUndead) {
if (invisible_undead && (invisible_undead > other->SeeInvisibleUndead())) {
return true;
}
}
//check invis vs. animals. //TODO: should we have a specific see invisible animal stat or this how live does it?
if (other->GetBodyType() == BT_Animal){
if (other->GetBodyType() == BodyType::Animal){
if (invisible_animals && (invisible_animals > other->SeeInvisible())) {
return true;
}
@@ -2913,7 +2913,7 @@ void Mob::ShowStats(Client* c)
}
// Body
auto bodytype_name = EQ::constants::GetBodyTypeName(t->GetBodyType());
auto bodytype_name = BodyType::GetName(t->GetBodyType());
c->Message(
Chat::White,
fmt::format(
@@ -7073,7 +7073,7 @@ bool Mob::IsControllableBoat() const {
);
}
void Mob::SetBodyType(bodyType new_body, bool overwrite_orig) {
void Mob::SetBodyType(uint8 new_body, bool overwrite_orig) {
bool needs_spawn_packet = false;
if(bodytype == 11 || bodytype >= 65 || new_body == 11 || new_body >= 65) {
needs_spawn_packet = true;
+7 -7
View File
@@ -143,7 +143,7 @@ public:
uint8 in_gender,
uint16 in_race,
uint8 in_class,
bodyType in_bodytype,
uint8 in_bodytype,
uint8 in_deity,
uint8 in_level,
uint32 in_npctype_id,
@@ -236,7 +236,7 @@ public:
bool CheckHitChance(Mob* attacker, DamageHitInfo &hit);
bool RollMeleeCritCheck(Mob *defender, EQ::skills::SkillType skill);
inline bool CanUndeadSlay() { return static_cast<bool>(GetUndeadSlayRate());}
inline bool IsUndeadForSlay() { return (GetBodyType() == BT_Undead || GetBodyType() == BT_SummonedUndead || GetBodyType() == BT_Vampire); }
inline bool IsUndeadForSlay() { return (GetBodyType() == BodyType::Undead || GetBodyType() == BodyType::SummonedUndead || GetBodyType() == BodyType::Vampire); }
int GetUndeadSlayRate();
void DoUndeadSlay(DamageHitInfo &hit, int crit_mod);
void TryCriticalHit(Mob *defender, DamageHitInfo &hit, ExtraAttackOptions *opts = nullptr);
@@ -1098,9 +1098,9 @@ public:
int GetPetACBonusFromOwner();
int GetPetATKBonusFromOwner();
inline const bodyType GetBodyType() const { return bodytype; }
inline const bodyType GetOrigBodyType() const { return orig_bodytype; }
void SetBodyType(bodyType new_body, bool overwrite_orig);
inline const uint8 GetBodyType() const { return bodytype; }
inline const uint8 GetOrigBodyType() const { return orig_bodytype; }
void SetBodyType(uint8 new_body, bool overwrite_orig);
bool invulnerable;
bool qglobal;
@@ -1575,8 +1575,8 @@ protected:
uint8 base_gender;
uint16 base_race;
uint8 class_;
bodyType bodytype;
bodyType orig_bodytype;
uint8 bodytype;
uint8 orig_bodytype;
uint16 deity;
uint8 level;
uint8 orig_level;
+1 -1
View File
@@ -443,7 +443,7 @@ void Mob::AI_Start(uint32 iMoveDelay) {
AI_feign_remember_timer = std::make_unique<Timer>(AIfeignremember_delay);
AI_scan_door_open_timer = std::make_unique<Timer>(AI_scan_door_open_interval);
if (GetBodyType() == BT_Animal && !RuleB(NPC, AnimalsOpenDoors)) {
if (GetBodyType() == BodyType::Animal && !RuleB(NPC, AnimalsOpenDoors)) {
SetCanOpenDoors(false);
}
+13 -6
View File
@@ -76,7 +76,7 @@ NPC::NPC(const NPCType *npc_type_data, Spawn2 *in_respawn, const glm::vec4 &posi
npc_type_data->gender,
npc_type_data->race,
npc_type_data->class_,
(bodyType) npc_type_data->bodytype,
npc_type_data->bodytype,
npc_type_data->deity,
npc_type_data->level,
npc_type_data->npc_id,
@@ -451,7 +451,7 @@ NPC::NPC(const NPCType *npc_type_data, Spawn2 *in_respawn, const glm::vec4 &posi
RestoreMana();
if (GetBodyType() == BT_Animal && !RuleB(NPC, AnimalsOpenDoors)) {
if (GetBodyType() == BodyType::Animal && !RuleB(NPC, AnimalsOpenDoors)) {
m_can_open_doors = false;
}
@@ -582,7 +582,7 @@ bool NPC::Process()
Mob* owner = entity_list.GetMob(ownerid);
if (owner != 0)
{
//if(GetBodyType() != BT_SwarmPet)
//if(GetBodyType() != BodyType::SwarmPet)
// owner->SetPetID(0);
ownerid = 0;
petid = 0;
@@ -1183,7 +1183,14 @@ NPC* NPC::SpawnNPC(const char* spawncommand, const glm::vec4& position, Client*
}
if (npc->bodytype) {
client->Message(Chat::White, fmt::format("Body Type | {} ({})", EQ::constants::GetBodyTypeName(npc->bodytype), npc->bodytype).c_str());
client->Message(
Chat::White,
fmt::format(
"Body Type | {} ({})",
BodyType::GetName(npc->bodytype),
npc->bodytype
).c_str()
);
}
client->Message(Chat::White, "New NPC spawned!");
@@ -1836,7 +1843,7 @@ void NPC::Disarm(Client* client, int chance) {
int matslot = eslot == EQ::invslot::slotPrimary ? EQ::textures::weaponPrimary : EQ::textures::weaponSecondary;
if (matslot != -1)
SendWearChange(matslot);
if ((CastToMob()->GetBodyType() == BT_Humanoid || CastToMob()->GetBodyType() == BT_Summoned) && eslot == EQ::invslot::slotPrimary)
if ((CastToMob()->GetBodyType() == BodyType::Humanoid || CastToMob()->GetBodyType() == BodyType::Summoned) && eslot == EQ::invslot::slotPrimary)
Say("Ahh! My weapon!");
client->MessageString(Chat::Skills, DISARM_SUCCESS, GetCleanName());
if (chance != 1000)
@@ -2200,7 +2207,7 @@ void NPC::PetOnSpawn(NewSpawn_Struct* ns)
//Not recommended if using above (However, this will work better on older clients).
if (RuleB(Pets, UnTargetableSwarmPet)) {
ns->spawn.bodytype = BT_NoTarget;
ns->spawn.bodytype = BodyType::NoTarget;
}
if (
+1 -1
View File
@@ -313,7 +313,7 @@ public:
float GetSlowMitigation() const { return slow_mitigation; }
float GetAttackSpeed() const {return attack_speed;}
int GetAttackDelay() const {return attack_delay;}
bool IsAnimal() const { return(bodytype == BT_Animal); }
bool IsAnimal() const { return(bodytype == BodyType::Animal); }
uint16 GetPetSpellID() const {return pet_spell_id;}
void SetPetSpellID(uint16 amt) {pet_spell_id = amt;}
uint32 GetMaxDamage(uint8 tlevel);
+10
View File
@@ -1293,3 +1293,13 @@ void Object::FixZ()
}
}
}
std::string ObjectType::GetName(uint32 object_type)
{
return IsValid(object_type) ? object_types[object_type] : "UNKNOWN OBJECT TYPE";
}
bool ObjectType::IsValid(uint32 object_type)
{
return object_types.find(object_type) != object_types.end();
}
+131
View File
@@ -250,4 +250,135 @@ protected:
void FixZ();
};
namespace ObjectType {
constexpr uint32 SmallBag = 0;
constexpr uint32 LargeBag = 1;
constexpr uint32 Quiver = 2;
constexpr uint32 BeltPouch = 3;
constexpr uint32 WristPouch = 4;
constexpr uint32 Backpack = 5;
constexpr uint32 SmallChest = 6;
constexpr uint32 LargeChest = 7;
constexpr uint32 Bandolier = 8;
constexpr uint32 Medicine = 9;
constexpr uint32 Tinkering = 10;
constexpr uint32 Lexicon = 11;
constexpr uint32 PoisonMaking = 12;
constexpr uint32 Quest = 13;
constexpr uint32 MixingBowl = 14;
constexpr uint32 Baking = 15;
constexpr uint32 Tailoring = 16;
constexpr uint32 Blacksmithing = 17;
constexpr uint32 Fletching = 18;
constexpr uint32 Brewing = 19;
constexpr uint32 JewelryMaking = 20;
constexpr uint32 Pottery = 21;
constexpr uint32 Kiln = 22;
constexpr uint32 KeyMaker = 23;
constexpr uint32 ResearchWIZ = 24;
constexpr uint32 ResearchMAG = 25;
constexpr uint32 ResearchNEC = 26;
constexpr uint32 ResearchENC = 27;
constexpr uint32 Unknown = 28;
constexpr uint32 ResearchPractice = 29;
constexpr uint32 Alchemy = 30;
constexpr uint32 HighElfForge = 31;
constexpr uint32 DarkElfForge = 32;
constexpr uint32 OgreForge = 33;
constexpr uint32 DwarfForge = 34;
constexpr uint32 GnomeForge = 35;
constexpr uint32 BarbarianForge = 36;
constexpr uint32 IksarForge = 37;
constexpr uint32 HumanForgeOne = 38;
constexpr uint32 HumanForgeTwo = 39;
constexpr uint32 HalflingTailoringOne = 40;
constexpr uint32 HalflingTailoringTwo = 41;
constexpr uint32 EruditeTailoring = 42;
constexpr uint32 WoodElfTailoring = 43;
constexpr uint32 WoodElfFletching = 44;
constexpr uint32 IksarPottery = 45;
constexpr uint32 Fishing = 46;
constexpr uint32 TrollForge = 47;
constexpr uint32 WoodElfForge = 48;
constexpr uint32 HalflingForge = 49;
constexpr uint32 EruditeForge = 50;
constexpr uint32 Merchant = 51;
constexpr uint32 FroglokForge = 52;
constexpr uint32 Augmenter = 53;
constexpr uint32 Churn = 54;
constexpr uint32 TransformationMold = 55;
constexpr uint32 DetransformationMold = 56;
constexpr uint32 Unattuner = 57;
constexpr uint32 TradeskillBag = 58;
constexpr uint32 CollectibleBag = 59;
constexpr uint32 NoDeposit = 60;
std::string GetName(uint32 object_type);
bool IsValid(uint32 object_type);
}
static std::map<uint32, std::string> object_types = {
{ ObjectType::SmallBag, "Small Bag" },
{ ObjectType::LargeBag, "Large Bag" },
{ ObjectType::Quiver, "Quiver" },
{ ObjectType::BeltPouch, "Belt Pouch" },
{ ObjectType::WristPouch, "Wrist Pouch" },
{ ObjectType::Backpack, "Backpack" },
{ ObjectType::SmallChest, "Small Chest" },
{ ObjectType::LargeChest, "Large Chest" },
{ ObjectType::Bandolier, "Bandolier" },
{ ObjectType::Medicine, "Medicine" },
{ ObjectType::Tinkering, "Tinkering" },
{ ObjectType::Lexicon, "Lexicon" },
{ ObjectType::PoisonMaking, "Mortar and Pestle" },
{ ObjectType::Quest, "Quest" },
{ ObjectType::MixingBowl, "Mixing Bowl" },
{ ObjectType::Baking, "Baking" },
{ ObjectType::Tailoring, "Tailoring" },
{ ObjectType::Blacksmithing, "Blacksmithing" },
{ ObjectType::Fletching, "Fletching" },
{ ObjectType::Brewing, "Brewing" },
{ ObjectType::JewelryMaking, "Jewelry Making" },
{ ObjectType::Pottery, "Pottery" },
{ ObjectType::Kiln, "Kiln" },
{ ObjectType::KeyMaker, "Key Maker" },
{ ObjectType::ResearchWIZ, "Lexicon" },
{ ObjectType::ResearchMAG, "Lexicon" },
{ ObjectType::ResearchNEC, "Lexicon" },
{ ObjectType::ResearchENC, "Lexicon" },
{ ObjectType::Unknown, "Unknown" },
{ ObjectType::ResearchPractice, "Lexicon" },
{ ObjectType::Alchemy, "Alchemy" },
{ ObjectType::HighElfForge, "High Elf Forge" },
{ ObjectType::DarkElfForge, "Dark Elf Forge" },
{ ObjectType::OgreForge, "Ogre Forge" },
{ ObjectType::DwarfForge, "Dwarf Forge" },
{ ObjectType::GnomeForge, "Gnome Forge" },
{ ObjectType::BarbarianForge, "Barbarian Forge" },
{ ObjectType::IksarForge, "Iksar Forge" },
{ ObjectType::HumanForgeOne, "Human Forge" },
{ ObjectType::HumanForgeTwo, "Human Forge" },
{ ObjectType::HalflingTailoringOne, "Halfling Tailoring" },
{ ObjectType::HalflingTailoringTwo, "Halfling Tailoring" },
{ ObjectType::EruditeTailoring, "Erudite Tailoring" },
{ ObjectType::WoodElfTailoring, "Wood Elf Tailoring" },
{ ObjectType::WoodElfFletching, "Wood Elf Fletching" },
{ ObjectType::IksarPottery, "Iksar Pottery" },
{ ObjectType::Fishing, "Fishing" },
{ ObjectType::TrollForge, "Troll Forge" },
{ ObjectType::WoodElfForge, "Wood Elf Forge" },
{ ObjectType::HalflingForge, "Halfling Forge" },
{ ObjectType::EruditeForge, "Erudite Forge" },
{ ObjectType::Merchant, "Merchant" },
{ ObjectType::FroglokForge, "Froglok Forge" },
{ ObjectType::Augmenter, "Augmenter" },
{ ObjectType::Churn, "Churn" },
{ ObjectType::TransformationMold, "Transformation Mold" },
{ ObjectType::DetransformationMold, "Detransformation Mold" },
{ ObjectType::Unattuner, "Unattuner" },
{ ObjectType::TradeskillBag, "Tradeskill Bag" },
{ ObjectType::CollectibleBag, "Collectible Bag" },
{ ObjectType::NoDeposit, "No Deposit" }
};
#endif
+6 -6
View File
@@ -2309,14 +2309,14 @@ bool Perl_Mob_IsRunning(Mob* self) // @categories Script Utility
return self->IsRunning();
}
void Perl_Mob_SetBodyType(Mob* self, int32 type) // @categories Stats and Attributes
void Perl_Mob_SetBodyType(Mob* self, uint8 body_type_id) // @categories Stats and Attributes
{
self->SetBodyType(static_cast<bodyType>(type), false);
self->SetBodyType(body_type_id, false);
}
void Perl_Mob_SetBodyType(Mob* self, int32 type, bool overwrite_orig) // @categories Stats and Attributes
void Perl_Mob_SetBodyType(Mob* self, uint8 body_type_id, bool overwrite_orig) // @categories Stats and Attributes
{
self->SetBodyType(static_cast<bodyType>(type), overwrite_orig);
self->SetBodyType(body_type_id, overwrite_orig);
}
void Perl_Mob_SetDeltas(Mob* self, float delta_x, float delta_y, float delta_z, float delta_h) // @categories Script Utility
@@ -4023,8 +4023,8 @@ void perl_register_mob()
package.add("SetAllowBeneficial", &Perl_Mob_SetAllowBeneficial);
package.add("SetAppearance", (void(*)(Mob*, int))&Perl_Mob_SetAppearance);
package.add("SetAppearance", (void(*)(Mob*, int, bool))&Perl_Mob_SetAppearance);
package.add("SetBodyType", (void(*)(Mob*, int32))&Perl_Mob_SetBodyType);
package.add("SetBodyType", (void(*)(Mob*, int32, bool))&Perl_Mob_SetBodyType);
package.add("SetBodyType", (void(*)(Mob*, uint8))&Perl_Mob_SetBodyType);
package.add("SetBodyType", (void(*)(Mob*, uint8, bool))&Perl_Mob_SetBodyType);
package.add("SetBucket", (void(*)(Mob*, std::string, std::string))&Perl_Mob_SetBucket);
package.add("SetBucket", (void(*)(Mob*, std::string, std::string, std::string))&Perl_Mob_SetBucket);
package.add("SetBuffDuration", (void(*)(Mob*, int))&Perl_Mob_SetBuffDuration);
+2 -2
View File
@@ -1483,8 +1483,8 @@ std::string QuestManager::getlanguagename(uint8 language_id) {
return EQ::constants::GetLanguageName(language_id);
}
std::string QuestManager::getbodytypename(uint32 bodytype_id) {
return EQ::constants::GetBodyTypeName(static_cast<bodyType>(bodytype_id));
std::string QuestManager::getbodytypename(uint8 body_type_id) {
return BodyType::GetName(body_type_id);
}
std::string QuestManager::getconsiderlevelname(uint8 consider_level) {
+1 -1
View File
@@ -121,7 +121,7 @@ public:
std::string getldonthemename(uint32 theme_id);
std::string getfactionname(int faction_id);
std::string getlanguagename(uint8 language_id);
std::string getbodytypename(uint32 bodytype_id);
std::string getbodytypename(uint8 body_type_id);
std::string getconsiderlevelname(uint8 consider_level);
void safemove();
void rain(int weather);
+4
View File
@@ -801,6 +801,10 @@ void SpawnConditionManager::UpdateSpawnEvent(SpawnEvent &event)
{
auto e = SpawnEventsRepository::FindOne(database, event.id);
if (!e.id) {
return;
}
e.next_minute = event.next.minute;
e.next_hour = event.next.hour;
e.next_day = event.next.day;
+3 -3
View File
@@ -1854,7 +1854,7 @@ void NPC::DoClassAttacks(Mob *target) {
IsTaunting() &&
HasOwner() &&
target->IsNPC() &&
target->GetBodyType() != BT_Undead &&
target->GetBodyType() != BodyType::Undead &&
taunt_time &&
type_of_pet &&
type_of_pet != petTargetLock &&
@@ -2403,7 +2403,7 @@ int Mob::TryHeadShot(Mob *defender, EQ::skills::SkillType skillInUse)
!defender->IsClient() &&
skillInUse == EQ::skills::SkillArchery &&
GetTarget() == defender &&
(defender->GetBodyType() == BT_Humanoid || !RuleB(Combat, HeadshotOnlyHumanoids)) &&
(defender->GetBodyType() == BodyType::Humanoid || !RuleB(Combat, HeadshotOnlyHumanoids)) &&
!defender->GetSpecialAbility(SpecialAbility::HeadshotImmunity)
) {
uint32 HeadShot_Dmg = aabonuses.HeadShot[SBIndex::FINISHING_EFFECT_DMG] + spellbonuses.HeadShot[SBIndex::FINISHING_EFFECT_DMG] + itembonuses.HeadShot[SBIndex::FINISHING_EFFECT_DMG];
@@ -2440,7 +2440,7 @@ int Mob::TryAssassinate(Mob *defender, EQ::skills::SkillType skillInUse)
!defender->IsClient() &&
GetLevel() >= RuleI(Combat, AssassinateLevelRequirement) &&
(skillInUse == EQ::skills::SkillBackstab || skillInUse == EQ::skills::SkillThrowing) &&
(defender->GetBodyType() == BT_Humanoid || !RuleB(Combat, AssassinateOnlyHumanoids)) &&
(defender->GetBodyType() == BodyType::Humanoid || !RuleB(Combat, AssassinateOnlyHumanoids)) &&
!defender->GetSpecialAbility(SpecialAbility::AssassinateImmunity)
) {
int chance = GetDEX();
+38 -32
View File
@@ -878,18 +878,18 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
{
if (CastToClient()->ClientVersionBit() & EQ::versions::maskSoDAndLater)
{
bodyType bt = BT_Undead;
uint8 bt = BodyType::Undead;
int MessageID = SENSE_UNDEAD;
if(effect == SE_SenseSummoned)
{
bt = BT_Summoned;
bt = BodyType::Summoned;
MessageID = SENSE_SUMMONED;
}
else if(effect == SE_SenseAnimals)
{
bt = BT_Animal;
bt = BodyType::Animal;
MessageID = SENSE_ANIMAL;
}
@@ -2329,6 +2329,12 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
if (IsClient()) {
int pre_aggro_count = CastToClient()->GetAggroCount();
entity_list.RemoveFromTargetsFadingMemories(this, true, max_level);
if (spellbonuses.ShroudofStealth || aabonuses.ShroudofStealth || itembonuses.ShroudofStealth) {
improved_hidden = true;
hidden = true;
}
SetInvisible(Invisibility::Invisible);
int post_aggro_count = CastToClient()->GetAggroCount();
if (RuleB(Spells, UseFadingMemoriesMaxLevel)) {
@@ -2758,7 +2764,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
case SE_SetBodyType:
{
SetBodyType((bodyType)spell.base_value[i], false);
SetBodyType(spell.base_value[i], false);
break;
}
@@ -7562,47 +7568,47 @@ bool Mob::PassCastRestriction(int value)
break;
case IS_ANIMAL_OR_HUMANOID:
if ((GetBodyType() == BT_Animal) || (GetBodyType() == BT_Humanoid))
if ((GetBodyType() == BodyType::Animal) || (GetBodyType() == BodyType::Humanoid))
return true;
break;
case IS_DRAGON:
if (GetBodyType() == BT_Dragon || GetBodyType() == BT_VeliousDragon || GetBodyType() == BT_Dragon3)
if (GetBodyType() == BodyType::Dragon || GetBodyType() == BodyType::VeliousDragon || GetBodyType() == BodyType::Dragon3)
return true;
break;
case IS_ANIMAL_OR_INSECT:
if ((GetBodyType() == BT_Animal) || (GetBodyType() == BT_Insect))
if ((GetBodyType() == BodyType::Animal) || (GetBodyType() == BodyType::Insect))
return true;
break;
case IS_BODY_TYPE_MISC:
if ((GetBodyType() == BT_Humanoid) || (GetBodyType() == BT_Lycanthrope) || (GetBodyType() == BT_Giant) ||
(GetBodyType() == BT_RaidGiant) || (GetBodyType() == BT_RaidColdain) || (GetBodyType() == BT_Animal)||
(GetBodyType() == BT_Construct) || (GetBodyType() == BT_Dragon) || (GetBodyType() == BT_Insect)||
(GetBodyType() == BT_VeliousDragon) || (GetBodyType() == BT_Muramite) || (GetBodyType() == BT_Magical))
if ((GetBodyType() == BodyType::Humanoid) || (GetBodyType() == BodyType::Lycanthrope) || (GetBodyType() == BodyType::Giant) ||
(GetBodyType() == BodyType::RaidGiant) || (GetBodyType() == BodyType::RaidColdain) || (GetBodyType() == BodyType::Animal)||
(GetBodyType() == BodyType::Construct) || (GetBodyType() == BodyType::Dragon) || (GetBodyType() == BodyType::Insect)||
(GetBodyType() == BodyType::VeliousDragon) || (GetBodyType() == BodyType::Muramite) || (GetBodyType() == BodyType::Magical))
return true;
break;
case IS_BODY_TYPE_MISC2:
if ((GetBodyType() == BT_Humanoid) || (GetBodyType() == BT_Lycanthrope) || (GetBodyType() == BT_Giant) ||
(GetBodyType() == BT_RaidGiant) || (GetBodyType() == BT_RaidColdain) || (GetBodyType() == BT_Animal) ||
(GetBodyType() == BT_Insect))
if ((GetBodyType() == BodyType::Humanoid) || (GetBodyType() == BodyType::Lycanthrope) || (GetBodyType() == BodyType::Giant) ||
(GetBodyType() == BodyType::RaidGiant) || (GetBodyType() == BodyType::RaidColdain) || (GetBodyType() == BodyType::Animal) ||
(GetBodyType() == BodyType::Insect))
return true;
break;
case IS_PLANT:
if (GetBodyType() == BT_Plant)
if (GetBodyType() == BodyType::Plant)
return true;
break;
case IS_GIANT:
if (GetBodyType() == BT_Giant)
if (GetBodyType() == BodyType::Giant)
return true;
break;
case IS_NOT_ANIMAL_OR_HUMANOID:
if ((GetBodyType() != BT_Animal) || (GetBodyType() != BT_Humanoid))
if ((GetBodyType() != BodyType::Animal) || (GetBodyType() != BodyType::Humanoid))
return true;
break;
@@ -7643,17 +7649,17 @@ bool Mob::PassCastRestriction(int value)
break;
case IS_UNDEAD_OR_VALDEHOLM_GIANT:
if (GetBodyType() == BT_Undead || GetRace() == Race::Giant2 || GetRace() == Race::Giant3)
if (GetBodyType() == BodyType::Undead || GetRace() == Race::Giant2 || GetRace() == Race::Giant3)
return true;
break;
case IS_ANIMAL_OR_PLANT:
if ((GetBodyType() == BT_Animal) || (GetBodyType() == BT_Plant))
if ((GetBodyType() == BodyType::Animal) || (GetBodyType() == BodyType::Plant))
return true;
break;
case IS_SUMMONED:
if (GetBodyType() == BT_Summoned)
if (GetBodyType() == BodyType::Summoned)
return true;
break;
@@ -7664,12 +7670,12 @@ bool Mob::PassCastRestriction(int value)
break;
case IS_UNDEAD:
if (GetBodyType() == BT_Undead)
if (GetBodyType() == BodyType::Undead)
return true;
break;
case IS_NOT_UNDEAD_OR_SUMMONED_OR_VAMPIRE:
if ((GetBodyType() != BT_Undead) && (GetBodyType() != BT_Summoned) && (GetBodyType() != BT_Vampire))
if ((GetBodyType() != BodyType::Undead) && (GetBodyType() != BodyType::Summoned) && (GetBodyType() != BodyType::Vampire))
return true;
break;
@@ -7679,12 +7685,12 @@ bool Mob::PassCastRestriction(int value)
break;
case IS_HUMANOID:
if (GetBodyType() == BT_Humanoid)
if (GetBodyType() == BodyType::Humanoid)
return true;
break;
case IS_UNDEAD_AND_HP_LESS_THAN_10_PCT:
if ((GetBodyType() == BT_Undead) && (GetHPRatio() < 10))
if ((GetBodyType() == BodyType::Undead) && (GetHPRatio() < 10))
return true;
break;
@@ -8042,12 +8048,12 @@ bool Mob::PassCastRestriction(int value)
break;
case IS_NOT_UNDEAD_OR_SUMMONED:
if ((GetBodyType() != BT_Undead) && (GetBodyType() != BT_Summoned))
if ((GetBodyType() != BodyType::Undead) && (GetBodyType() != BodyType::Summoned))
return true;
break;
case IS_NOT_PLANT:
if (GetBodyType() != BT_Plant)
if (GetBodyType() != BodyType::Plant)
return true;
break;
@@ -8077,12 +8083,12 @@ bool Mob::PassCastRestriction(int value)
break;
case IS_VAMPIRE_OR_UNDEAD_OR_UNDEADPET:
if (GetBodyType() == BT_Vampire || GetBodyType() == BT_Undead || GetBodyType() == BT_SummonedUndead)
if (GetBodyType() == BodyType::Vampire || GetBodyType() == BodyType::Undead || GetBodyType() == BodyType::SummonedUndead)
return true;
break;
case IS_NOT_VAMPIRE_OR_UNDEAD:
if (GetBodyType() != BT_Vampire && GetBodyType() != BT_Undead && GetBodyType() != BT_SummonedUndead)
if (GetBodyType() != BodyType::Vampire && GetBodyType() != BodyType::Undead && GetBodyType() != BodyType::SummonedUndead)
return true;
break;
@@ -8124,17 +8130,17 @@ bool Mob::PassCastRestriction(int value)
break;
case IS_HUMANOID_LEVEL_84_MAX:
if (GetBodyType() == BT_Humanoid && GetLevel() <= 84)
if (GetBodyType() == BodyType::Humanoid && GetLevel() <= 84)
return true;
break;
case IS_HUMANOID_LEVEL_86_MAX:
if (GetBodyType() == BT_Humanoid && GetLevel() <= 86)
if (GetBodyType() == BodyType::Humanoid && GetLevel() <= 86)
return true;
break;
case IS_HUMANOID_LEVEL_88_MAX:
if (GetBodyType() == BT_Humanoid && GetLevel() <= 88)
if (GetBodyType() == BodyType::Humanoid && GetLevel() <= 88)
return true;
break;
@@ -8312,7 +8318,7 @@ bool Mob::PassCastRestriction(int value)
break;
case IS_SUMMONED_OR_UNDEAD:
if (GetBodyType() == BT_Summoned || GetBodyType() == BT_Undead)
if (GetBodyType() == BodyType::Summoned || GetBodyType() == BodyType::Undead)
return true;
break;
+21 -24
View File
@@ -1955,9 +1955,9 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce
// during this switch, this variable gets set to one of these things
// and that causes the spell to be executed differently
bodyType target_bt = BT_Humanoid;
uint8 target_bt = BodyType::Humanoid;
SpellTargetType targetType = spells[spell_id].target_type;
bodyType mob_body = spell_target ? spell_target->GetBodyType() : BT_Humanoid;
uint8 mob_body = spell_target ? spell_target->GetBodyType() : BodyType::Humanoid;
if(IsIllusionSpell(spell_id)
&& spell_target != nullptr // null ptr crash safeguard
@@ -2000,9 +2000,9 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce
// target required for these
case ST_Undead: {
if(!spell_target || (
mob_body != BT_SummonedUndead
&& mob_body != BT_Undead
&& mob_body != BT_Vampire
mob_body != BodyType::SummonedUndead
&& mob_body != BodyType::Undead
&& mob_body != BodyType::Vampire
)
)
{
@@ -2019,7 +2019,7 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce
}
case ST_Summoned: {
if(!spell_target || (mob_body != BT_Summoned && mob_body != BT_Summoned2 && mob_body != BT_Summoned3))
if(!spell_target || (mob_body != BodyType::Summoned && mob_body != BodyType::Summoned2 && mob_body != BodyType::Summoned3))
{
//invalid target
LogSpells("Spell [{}] canceled: invalid target of body type [{}] (summoned)", spell_id, mob_body);
@@ -2033,7 +2033,7 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce
case ST_SummonedPet:
{
if(!spell_target || (spell_target != GetPet()) ||
(mob_body != BT_Summoned && mob_body != BT_Summoned2 && mob_body != BT_Summoned3 && mob_body != BT_Animal))
(mob_body != BodyType::Summoned && mob_body != BodyType::Summoned2 && mob_body != BodyType::Summoned3 && mob_body != BodyType::Animal))
{
LogSpells("Spell [{}] canceled: invalid target of body type [{}] (summoned pet)",
spell_id, mob_body);
@@ -2047,14 +2047,14 @@ bool Mob::DetermineSpellTargets(uint16 spell_id, Mob *&spell_target, Mob *&ae_ce
}
//single body type target spells...
//this is a little hackish, but better than duplicating code IMO
case ST_Plant: if(target_bt == BT_Humanoid) target_bt = BT_Plant;
case ST_Dragon: if(target_bt == BT_Humanoid) target_bt = BT_Dragon;
case ST_Giant: if(target_bt == BT_Humanoid) target_bt = BT_Giant;
case ST_Animal: if(target_bt == BT_Humanoid) target_bt = BT_Animal;
case ST_Plant: if(target_bt == BodyType::Humanoid) target_bt = BodyType::Plant;
case ST_Dragon: if(target_bt == BodyType::Humanoid) target_bt = BodyType::Dragon;
case ST_Giant: if(target_bt == BodyType::Humanoid) target_bt = BodyType::Giant;
case ST_Animal: if(target_bt == BodyType::Humanoid) target_bt = BodyType::Animal;
// check for special case body types (Velious dragons/giants)
if(mob_body == BT_RaidGiant) mob_body = BT_Giant;
if(mob_body == BT_VeliousDragon) mob_body = BT_Dragon;
if(mob_body == BodyType::RaidGiant) mob_body = BodyType::Giant;
if(mob_body == BodyType::VeliousDragon) mob_body = BodyType::Dragon;
{
if(!spell_target || mob_body != target_bt)
@@ -4120,8 +4120,8 @@ bool Mob::SpellOnTarget(
}
//cannot hurt untargetable mobs
bodyType bt = spelltar->GetBodyType();
if (bt == BT_NoTarget || bt == BT_NoTarget2) {
uint8 bt = spelltar->GetBodyType();
if (bt == BodyType::NoTarget || bt == BodyType::NoTarget2) {
if (RuleB(Pets, UnTargetableSwarmPet)) {
if (spelltar->IsNPC()) {
if (!spelltar->CastToNPC()->GetSwarmOwner()) {
@@ -4303,9 +4303,9 @@ bool Mob::SpellOnTarget(
//check for AE_Undead
if (spells[spell_id].target_type == ST_UndeadAE){
if (
spelltar->GetBodyType() != BT_SummonedUndead &&
spelltar->GetBodyType() != BT_Undead &&
spelltar->GetBodyType() != BT_Vampire
spelltar->GetBodyType() != BodyType::SummonedUndead &&
spelltar->GetBodyType() != BodyType::Undead &&
spelltar->GetBodyType() != BodyType::Vampire
) {
safe_delete(action_packet);
return false;
@@ -5315,19 +5315,16 @@ float Mob::ResistSpell(uint8 resist_type, uint16 spell_id, Mob *caster, bool use
}
}
if (!CharmTick){
if (!CharmTick) {
//Check for Spell Effect specific resistance chances (ie AA Mental Fortitude)
int se_resist_bonuses = GetSpellEffectResistChance(spell_id);
if(se_resist_bonuses && zone->random.Roll(se_resist_bonuses))
{
if (se_resist_bonuses && zone->random.Roll(se_resist_bonuses)) {
return 0;
}
// Check for Chance to Resist Spell bonuses (ie Sanctification Discipline)
int resist_bonuses = CalcResistChanceBonus();
if(resist_bonuses && zone->random.Roll(resist_bonuses))
{
if (resist_bonuses && zone->random.Roll(resist_bonuses) && !IsResurrectionSicknessSpell(spell_id)) {
LogSpells("Resisted spell in sanctification, had [{}] chance to resist", resist_bonuses);
return 0;
}
+15 -4
View File
@@ -1049,6 +1049,10 @@ void Client::TraderStartTrader(const EQApplicationPacket *app)
//Check inventory for no-trade items
for (auto const &i: inv->serial_number) {
if (i <= 0) {
continue;
}
auto inst = FindTraderItemBySerialNumber(i);
if (inst) {
if (inst->GetItem() && inst->GetItem()->NoDrop == 0) {
@@ -1067,7 +1071,16 @@ void Client::TraderStartTrader(const EQApplicationPacket *app)
}
for (uint32 i = 0; i < max_items; i++) {
if (inv->serial_number[i] <= 0) {
continue;
}
auto inst = FindTraderItemBySerialNumber(inv->serial_number[i]);
if (!inst) {
trade_items_valid = false;
break;
}
auto it = std::find(std::begin(in->serial_number), std::end(in->serial_number), inv->serial_number[i]);
if (inst && it != std::end(in->serial_number)) {
inst->SetPrice(in->item_cost[i]);
@@ -1106,18 +1119,16 @@ void Client::TraderStartTrader(const EQApplicationPacket *app)
trade_items_valid = false;
continue;
}
else if (!in->serial_number[i]) {
break;
}
}
if (!trade_items_valid) {
Message(Chat::Red, "You are not able to become a trader at this time.");
Message(Chat::Red, "You are not able to become a trader at this time. Invalid item found.");
TraderEndTrader();
safe_delete(inv);
return;
}
TraderRepository::DeleteWhere(database, fmt::format("`char_id` = '{}';", CharacterID()));
TraderRepository::ReplaceMany(database, trader_items);
safe_delete(inv);
+1 -1
View File
@@ -521,7 +521,7 @@ void Trap::CreateHiddenTrigger()
make_npc->current_hp = 100000;
strcpy(make_npc->name, "a_trap");
make_npc->runspeed = 0.0f;
make_npc->bodytype = BT_Special;
make_npc->bodytype = BodyType::Special;
make_npc->race = 127;
make_npc->gender = Gender::Male;
make_npc->loottable_id = 0;
-7
View File
@@ -1194,13 +1194,6 @@ bool Zone::Init(bool is_static) {
LoadZoneObjects();
LoadZoneDoors();
LoadZoneBlockedSpells();
//clear trader items if we are loading the bazaar
if (strncasecmp(short_name, "bazaar", 6) == 0) {
TraderRepository::Truncate(database);
database.DeleteBuyLines(0);
}
LoadVeteranRewards();
LoadAlternateCurrencies();
LoadNPCEmotes(&npc_emote_list);
+1
View File
@@ -318,6 +318,7 @@ std::unique_ptr<EQ::ItemInstance> ZoneDatabase::LoadSingleTraderItem(uint32 char
if (results.empty()) {
LogTrading("Could not find item serial number {} for character id {}", serial_number, char_id);
return nullptr;
}
int item_id = results.at(0).item_id;